signalwire-sdk 3.2.0.dev97__tar.gz → 3.3.0.dev100__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.2.0.dev97/signalwire/signalwire_sdk.egg-info → signalwire_sdk-3.3.0.dev100}/PKG-INFO +2 -1
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/pyproject.toml +2 -1
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/__init__.py +6 -1
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/agent_server.py +1 -1
- signalwire_sdk-3.3.0.dev100/signalwire/signalwire/ai_chat/__init__.py +37 -0
- signalwire_sdk-3.3.0.dev100/signalwire/signalwire/ai_chat/client.py +344 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/swml_verbs_generated.py +55 -6
- signalwire_sdk-3.3.0.dev100/signalwire/signalwire/schema.json +12616 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100/signalwire/signalwire_sdk.egg-info}/PKG-INFO +2 -1
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire_sdk.egg-info/SOURCES.txt +2 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire_sdk.egg-info/requires.txt +1 -0
- signalwire_sdk-3.2.0.dev97/signalwire/signalwire/schema.json +0 -12533
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/LICENSE +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/README.md +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/man/sw-agent-init.1 +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/man/sw-search.1 +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/man/swaig-test.1 +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/setup.cfg +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/setup.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/agents/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/agents/bedrock.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/cli/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/cli/build_search.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/cli/config.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/cli/core/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/cli/core/agent_loader.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/cli/core/argparse_helpers.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/cli/core/dynamic_config.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/cli/core/service_loader.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/cli/dokku.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/cli/execution/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/cli/execution/datamap_exec.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/cli/execution/webhook_exec.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/cli/init_project.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/cli/output/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/cli/output/output_formatter.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/cli/output/swml_dump.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/cli/simulation/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/cli/simulation/data_generation.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/cli/simulation/data_overrides.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/cli/simulation/mock_env.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/cli/swaig_test_wrapper.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/cli/test_swaig.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/cli/types.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/_agent_host.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/agent/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/agent/config/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/agent/deployment/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/agent/deployment/handlers/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/agent/prompt/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/agent/prompt/manager.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/agent/routing/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/agent/security/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/agent/swml/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/agent/tools/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/agent/tools/decorator.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/agent/tools/registry.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/agent/tools/type_inference.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/agent_base.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/auth_handler.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/config_loader.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/contexts.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/data_map.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/function_result.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/logging_config.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/mixins/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/mixins/_mixin_host.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/mixins/ai_config_mixin.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/mixins/auth_mixin.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/mixins/mcp_server_mixin.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/mixins/prompt_mixin.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/mixins/serverless_mixin.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/mixins/skill_mixin.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/mixins/state_mixin.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/mixins/tool_mixin.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/mixins/web_mixin.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/pom_builder.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/post_prompt_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/security/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/security/security_utils.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/security/session_manager.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/security/webhook_middleware.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/security/webhook_validator.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/security_config.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/skill_base.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/skill_manager.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/swaig_actions_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/swaig_function.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/swaig_request_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/swml_builder.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/swml_handler.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/swml_renderer.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/swml_service.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/core/web.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/livewire/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/livewire/plugins.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/mcp_gateway/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/mcp_gateway/gateway_service.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/mcp_gateway/mcp_manager.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/mcp_gateway/session_manager.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/pom/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/pom/pom.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/pom/pom_tool.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/prefabs/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/prefabs/concierge.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/prefabs/faq_bot.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/prefabs/info_gatherer.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/prefabs/receptionist.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/prefabs/survey.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/py.typed +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/relay/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/relay/call.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/relay/client.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/relay/constants.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/relay/event.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/relay/message.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/relay/protocol_types_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/_base.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/_pagination.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/_request_options.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/call_handler.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/client.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/_client_tree_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/addresses.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/calling.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/calling_resources_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/calling_types_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/chat.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/chat_resources_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/chat_types_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/datasphere.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/datasphere_resources_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/datasphere_types_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/fabric.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/fabric_resources_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/fabric_types_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/fax_resources_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/fax_types_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/imported_numbers.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/logs.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/logs_resources_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/logs_types_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/lookup.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/message_resources_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/message_types_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/messages_resources_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/messages_types_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/mfa.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/number_groups.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/phone_numbers.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/project.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/project_resources_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/project_types_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/projects_resources_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/projects_types_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/pubsub.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/pubsub_resources_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/pubsub_types_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/queues.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/recordings.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/registry.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/relay_rest_resources_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/relay_rest_types_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/short_codes.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/sip_profile.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/swml_webhooks_types_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/verified_callers.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/video.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/video_resources_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/video_types_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/voice_resources_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/rest/namespaces/voice_types_generated.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/search/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/search/document_processor.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/search/index_builder.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/search/migration.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/search/models.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/search/pgvector_backend.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/search/query_processor.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/search/search_engine.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/search/search_service.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/README.md +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/api_ninjas_trivia/README.md +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/api_ninjas_trivia/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/api_ninjas_trivia/skill.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/claude_skills/README.md +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/claude_skills/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/claude_skills/skill.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/datasphere/README.md +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/datasphere/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/datasphere/skill.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/datasphere_serverless/README.md +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/datasphere_serverless/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/datasphere_serverless/skill.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/datetime/README.md +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/datetime/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/datetime/skill.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/google_maps/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/google_maps/skill.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/info_gatherer/README.md +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/info_gatherer/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/info_gatherer/skill.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/joke/README.md +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/joke/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/joke/skill.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/math/README.md +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/math/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/math/skill.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/mcp_gateway/README.md +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/mcp_gateway/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/mcp_gateway/skill.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/native_vector_search/README.md +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/native_vector_search/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/native_vector_search/skill.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/play_background_file/README.md +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/play_background_file/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/play_background_file/skill.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/registry.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/spider/README.md +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/spider/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/spider/skill.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/swml_transfer/README.md +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/swml_transfer/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/swml_transfer/skill.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/weather_api/README.md +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/weather_api/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/weather_api/skill.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/web_search/README.md +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/web_search/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/web_search/skill.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/web_search/skill_improved.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/web_search/skill_original.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/wikipedia_search/README.md +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/wikipedia_search/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/skills/wikipedia_search/skill.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/utils/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/utils/pom_utils.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/utils/schema_utils.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/utils/token_generators.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/utils/url_validator.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/utils/validators.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/web/__init__.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/web/web_service.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire_sdk.egg-info/dependency_links.txt +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire_sdk.egg-info/entry_points.txt +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire_sdk.egg-info/top_level.txt +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/tests/test_examples.py +0 -0
- {signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/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.
|
|
3
|
+
Version: 3.3.0.dev100
|
|
4
4
|
Summary: SignalWire SDK
|
|
5
5
|
Author-email: SignalWire Team <info@signalwire.com>
|
|
6
6
|
License: MIT
|
|
@@ -17,6 +17,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
17
17
|
Requires-Python: >=3.10
|
|
18
18
|
Description-Content-Type: text/markdown
|
|
19
19
|
License-File: LICENSE
|
|
20
|
+
Requires-Dist: aiohttp>=3.9.0
|
|
20
21
|
Requires-Dist: fastapi>=0.115.12
|
|
21
22
|
Requires-Dist: pydantic>=2.11.4
|
|
22
23
|
Requires-Dist: PyYAML>=6.0.2
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "signalwire-sdk"
|
|
7
|
-
version = "3.
|
|
7
|
+
version = "3.3.0.dev100"
|
|
8
8
|
description = "SignalWire SDK"
|
|
9
9
|
authors = [
|
|
10
10
|
{name = "SignalWire Team", email = "info@signalwire.com"}
|
|
@@ -24,6 +24,7 @@ classifiers = [
|
|
|
24
24
|
"Programming Language :: Python :: 3.13",
|
|
25
25
|
]
|
|
26
26
|
dependencies = [
|
|
27
|
+
"aiohttp>=3.9.0",
|
|
27
28
|
"fastapi>=0.115.12",
|
|
28
29
|
"pydantic>=2.11.4",
|
|
29
30
|
"PyYAML>=6.0.2",
|
{signalwire_sdk-3.2.0.dev97 → signalwire_sdk-3.3.0.dev100}/signalwire/signalwire/__init__.py
RENAMED
|
@@ -52,7 +52,7 @@ if TYPE_CHECKING:
|
|
|
52
52
|
from signalwire.utils.schema_utils import SchemaValidationError
|
|
53
53
|
from signalwire.web import WebService
|
|
54
54
|
|
|
55
|
-
__version__ = "3.
|
|
55
|
+
__version__ = "3.3.0.dev100"
|
|
56
56
|
|
|
57
57
|
# §6.2-python (owner decision: NO packaging split — one package, all deps required;
|
|
58
58
|
# IMPORT-TIME behavior only): the agent/web symbols are lazy-imported via module
|
|
@@ -81,6 +81,10 @@ _LAZY_IMPORTS: dict[str, tuple[str, str]] = {
|
|
|
81
81
|
"BedrockAgent": ("signalwire.agents.bedrock", "BedrockAgent"),
|
|
82
82
|
"SchemaValidationError": ("signalwire.utils.schema_utils", "SchemaValidationError"),
|
|
83
83
|
"WebService": ("signalwire.web", "WebService"),
|
|
84
|
+
# AI Chat client — lazy so its aiohttp dep loads only on first access (mirrors how
|
|
85
|
+
# every other public client here is exposed; RestClient's factory form is the odd
|
|
86
|
+
# one out). Makes `from signalwire import AIChatClient` work like every sibling.
|
|
87
|
+
"AIChatClient": ("signalwire.ai_chat", "AIChatClient"),
|
|
84
88
|
}
|
|
85
89
|
|
|
86
90
|
|
|
@@ -195,6 +199,7 @@ def RestClient(*args: Any, **kwargs: Any) -> "_RestClient":
|
|
|
195
199
|
|
|
196
200
|
|
|
197
201
|
__all__ = [
|
|
202
|
+
"AIChatClient",
|
|
198
203
|
"AgentBase",
|
|
199
204
|
"AgentServer",
|
|
200
205
|
"BedrockAgent",
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Copyright (c) 2026 SignalWire
|
|
3
|
+
|
|
4
|
+
This file is part of the SignalWire SDK.
|
|
5
|
+
|
|
6
|
+
Licensed under the MIT License.
|
|
7
|
+
See LICENSE file in the project root for full license information.
|
|
8
|
+
|
|
9
|
+
Async client for the SignalWire AI Chat service — see
|
|
10
|
+
:mod:`signalwire.ai_chat.client` for the full protocol notes.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from .client import (
|
|
14
|
+
AIChatClient,
|
|
15
|
+
AIChatError,
|
|
16
|
+
AuthenticationError,
|
|
17
|
+
ChatInProgressError,
|
|
18
|
+
ChatLog,
|
|
19
|
+
ChatResponse,
|
|
20
|
+
ConversationInfo,
|
|
21
|
+
ConversationNotFoundError,
|
|
22
|
+
RateLimitError,
|
|
23
|
+
SummaryError,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
__all__ = [
|
|
27
|
+
"AIChatClient",
|
|
28
|
+
"AIChatError",
|
|
29
|
+
"AuthenticationError",
|
|
30
|
+
"ChatInProgressError",
|
|
31
|
+
"ChatLog",
|
|
32
|
+
"ChatResponse",
|
|
33
|
+
"ConversationInfo",
|
|
34
|
+
"ConversationNotFoundError",
|
|
35
|
+
"RateLimitError",
|
|
36
|
+
"SummaryError",
|
|
37
|
+
]
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Copyright (c) 2026 SignalWire
|
|
3
|
+
|
|
4
|
+
This file is part of the SignalWire SDK.
|
|
5
|
+
|
|
6
|
+
Licensed under the MIT License.
|
|
7
|
+
See LICENSE file in the project root for full license information.
|
|
8
|
+
|
|
9
|
+
Async client for the SignalWire AI Chat service.
|
|
10
|
+
|
|
11
|
+
The client speaks the standard SignalWire front-door protocol: HTTP Basic
|
|
12
|
+
``project:api_token`` with the space in the hostname —
|
|
13
|
+
``POST https://{space}.signalwire.com/api/ai/chat`` — carrying a JSON-RPC 2.0
|
|
14
|
+
body whose params are pure payload (identity never appears in the body).
|
|
15
|
+
|
|
16
|
+
Async-first by design: a ``chat()`` call waits on a full LLM round trip
|
|
17
|
+
(seconds, not milliseconds), and the typical consumers — bots, MCP servers —
|
|
18
|
+
run on asyncio event loops where a blocking HTTP call would stall every other
|
|
19
|
+
conversation. Use it as an async context manager::
|
|
20
|
+
|
|
21
|
+
from signalwire.ai_chat import AIChatClient
|
|
22
|
+
|
|
23
|
+
async with AIChatClient(space="myspace") as client: # env supplies creds
|
|
24
|
+
await client.create_conversation("conv-1", config_url=CONFIG_URL)
|
|
25
|
+
reply = await client.chat("conv-1", "hello")
|
|
26
|
+
print(reply.text)
|
|
27
|
+
|
|
28
|
+
URL resolution, in order:
|
|
29
|
+
|
|
30
|
+
1. ``url=`` constructor argument — used verbatim.
|
|
31
|
+
2. ``RAILS_DEV_MODE`` environment variable — a full URL used verbatim
|
|
32
|
+
(point it at a dev chat service, e.g. ``http://localhost:8080/``).
|
|
33
|
+
3. ``https://{space}.signalwire.com/api/ai/chat`` built from ``space``
|
|
34
|
+
(argument or ``SIGNALWIRE_SPACE``).
|
|
35
|
+
|
|
36
|
+
Credentials come from the constructor or the standard environment variables
|
|
37
|
+
``SIGNALWIRE_PROJECT_ID`` / ``SIGNALWIRE_API_TOKEN``.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
import os
|
|
41
|
+
from dataclasses import dataclass, field
|
|
42
|
+
from typing import Any
|
|
43
|
+
|
|
44
|
+
import aiohttp
|
|
45
|
+
|
|
46
|
+
from signalwire.rest._base import _user_agent
|
|
47
|
+
|
|
48
|
+
DEFAULT_PATH = "/api/ai/chat"
|
|
49
|
+
|
|
50
|
+
# The service streams keepalive whitespace ahead of slow responses (every
|
|
51
|
+
# ~10s), so liveness is byte-driven, not wall-clock: no total cap (turn
|
|
52
|
+
# length is the server's business), ``sock_read`` as the dead-connection
|
|
53
|
+
# detector (60s of true byte silence means the request is dead — the proxy
|
|
54
|
+
# itself severs after 30s of upstream silence), and a bounded connect.
|
|
55
|
+
# The leading whitespace is valid JSON, so ``resp.json()`` is unaffected.
|
|
56
|
+
# Pass your own ``session=`` to override.
|
|
57
|
+
DEFAULT_TIMEOUT = aiohttp.ClientTimeout(total=None, connect=10, sock_read=60)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
# ── Errors ───────────────────────────────────────────────────────────
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class AIChatError(Exception):
|
|
64
|
+
"""Base error for AI Chat service failures."""
|
|
65
|
+
|
|
66
|
+
def __init__(self, code: int | None, message: str) -> None:
|
|
67
|
+
self.code = code
|
|
68
|
+
self.message = message
|
|
69
|
+
super().__init__(f"[{code}] {message}")
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class AuthenticationError(AIChatError):
|
|
73
|
+
"""Missing/rejected identity (HTTP 401 / JSON-RPC -32009)."""
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class ConversationNotFoundError(AIChatError):
|
|
77
|
+
"""The conversation does not exist in this project (-32001)."""
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class RateLimitError(AIChatError):
|
|
81
|
+
"""Project or conversation rate limit hit (-32005 / -32006)."""
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class ChatInProgressError(AIChatError):
|
|
85
|
+
"""Another message is being processed for this conversation (-32007)."""
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class SummaryError(AIChatError):
|
|
89
|
+
"""Summary generation failed. ``summarize`` returns EXACTLY ONE of
|
|
90
|
+
``{summary}`` (success) or ``{error}`` (generation failed), and the failure
|
|
91
|
+
rides the JSON-RPC *success* envelope — not an ``error`` object — so it never
|
|
92
|
+
reaches the ``_ERROR_BY_CODE`` mapping. Surfaced here so a failed summary
|
|
93
|
+
can't masquerade as an empty string. ``code`` is None (no JSON-RPC code)."""
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
_ERROR_BY_CODE = {
|
|
97
|
+
-32001: ConversationNotFoundError,
|
|
98
|
+
-32005: RateLimitError,
|
|
99
|
+
-32006: RateLimitError,
|
|
100
|
+
-32007: ChatInProgressError,
|
|
101
|
+
-32009: AuthenticationError,
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
# ── Response models ──────────────────────────────────────────────────
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
@dataclass
|
|
109
|
+
class ConversationInfo:
|
|
110
|
+
id: str
|
|
111
|
+
status: str
|
|
112
|
+
initial_message: str | None = None
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
@dataclass
|
|
116
|
+
class ChatResponse:
|
|
117
|
+
text: str
|
|
118
|
+
conversation_id: str
|
|
119
|
+
user_event: dict[str, Any] | None = None
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
@dataclass
|
|
123
|
+
class ChatLog:
|
|
124
|
+
messages: list[dict[str, Any]] = field(default_factory=list)
|
|
125
|
+
call_timeline: list[dict[str, Any]] = field(default_factory=list)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
# ── Client ───────────────────────────────────────────────────────────
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class AIChatClient:
|
|
132
|
+
"""Async client for the SignalWire AI Chat service."""
|
|
133
|
+
|
|
134
|
+
def __init__(
|
|
135
|
+
self,
|
|
136
|
+
project: str | None = None,
|
|
137
|
+
token: str | None = None,
|
|
138
|
+
space: str | None = None,
|
|
139
|
+
url: str | None = None,
|
|
140
|
+
session: aiohttp.ClientSession | None = None,
|
|
141
|
+
) -> None:
|
|
142
|
+
self._project = project or os.environ.get("SIGNALWIRE_PROJECT_ID", "")
|
|
143
|
+
self._token = token or os.environ.get("SIGNALWIRE_API_TOKEN", "")
|
|
144
|
+
space = space or os.environ.get("SIGNALWIRE_SPACE", "")
|
|
145
|
+
|
|
146
|
+
if not self._project:
|
|
147
|
+
raise ValueError(
|
|
148
|
+
"project is required. Provide it as an argument or set the "
|
|
149
|
+
"SIGNALWIRE_PROJECT_ID environment variable."
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
self.url = self._resolve_url(url, space)
|
|
153
|
+
self._auth = aiohttp.BasicAuth(self._project, self._token)
|
|
154
|
+
self._headers = {"User-Agent": _user_agent()}
|
|
155
|
+
self._session = session
|
|
156
|
+
self._owns_session = session is None
|
|
157
|
+
self._request_counter = 0
|
|
158
|
+
|
|
159
|
+
@staticmethod
|
|
160
|
+
def _resolve_url(url: str | None, space: str) -> str:
|
|
161
|
+
if url:
|
|
162
|
+
return url
|
|
163
|
+
dev_url = os.environ.get("RAILS_DEV_MODE", "").strip()
|
|
164
|
+
if dev_url and dev_url.lower() not in (
|
|
165
|
+
"false",
|
|
166
|
+
"0",
|
|
167
|
+
"no",
|
|
168
|
+
"off",
|
|
169
|
+
"true",
|
|
170
|
+
"1",
|
|
171
|
+
"yes",
|
|
172
|
+
"on",
|
|
173
|
+
):
|
|
174
|
+
# RAILS_DEV_MODE doubles as the service's persona switch, so
|
|
175
|
+
# plain booleans mean "on" without carrying a URL — only a real
|
|
176
|
+
# URL-looking value overrides the target here.
|
|
177
|
+
return dev_url
|
|
178
|
+
if space:
|
|
179
|
+
return f"https://{space}.signalwire.com{DEFAULT_PATH}"
|
|
180
|
+
raise ValueError(
|
|
181
|
+
"No service URL: provide url=, set RAILS_DEV_MODE to a full URL, "
|
|
182
|
+
"or provide space= / SIGNALWIRE_SPACE."
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
# ── Session lifecycle ────────────────────────────────────────────
|
|
186
|
+
|
|
187
|
+
async def __aenter__(self) -> "AIChatClient":
|
|
188
|
+
await self._ensure_session()
|
|
189
|
+
return self
|
|
190
|
+
|
|
191
|
+
async def __aexit__(self, *exc: Any) -> None:
|
|
192
|
+
await self.close()
|
|
193
|
+
|
|
194
|
+
async def _ensure_session(self) -> aiohttp.ClientSession:
|
|
195
|
+
if self._session is None:
|
|
196
|
+
self._session = aiohttp.ClientSession(
|
|
197
|
+
auth=self._auth, headers=self._headers, timeout=DEFAULT_TIMEOUT
|
|
198
|
+
)
|
|
199
|
+
return self._session
|
|
200
|
+
|
|
201
|
+
async def close(self) -> None:
|
|
202
|
+
if self._owns_session and self._session is not None:
|
|
203
|
+
await self._session.close()
|
|
204
|
+
self._session = None
|
|
205
|
+
|
|
206
|
+
# ── Wire ─────────────────────────────────────────────────────────
|
|
207
|
+
|
|
208
|
+
async def _request(self, method: str, params: dict[str, Any]) -> dict[str, Any]:
|
|
209
|
+
session = await self._ensure_session()
|
|
210
|
+
self._request_counter += 1
|
|
211
|
+
payload = {
|
|
212
|
+
"jsonrpc": "2.0",
|
|
213
|
+
"method": method,
|
|
214
|
+
"params": params,
|
|
215
|
+
"id": f"req-{self._request_counter}",
|
|
216
|
+
}
|
|
217
|
+
async with session.post(self.url, json=payload) as resp:
|
|
218
|
+
try:
|
|
219
|
+
body = await resp.json()
|
|
220
|
+
except (aiohttp.ContentTypeError, ValueError) as err:
|
|
221
|
+
raise AIChatError(
|
|
222
|
+
resp.status, f"non-JSON response (HTTP {resp.status})"
|
|
223
|
+
) from err
|
|
224
|
+
# Success/failure is decided by the JSON-RPC body, NOT the HTTP status:
|
|
225
|
+
# the service's keepalive heartbeat commits ``200`` before the turn's
|
|
226
|
+
# outcome is known (heartbeat.py), so a slow error arrives as
|
|
227
|
+
# ``200 + {"error": …}``. Never gate on ``resp.status`` here.
|
|
228
|
+
if "error" in body:
|
|
229
|
+
error = body["error"] or {}
|
|
230
|
+
code = error.get("code")
|
|
231
|
+
exc_type = (
|
|
232
|
+
_ERROR_BY_CODE.get(code, AIChatError)
|
|
233
|
+
if code is not None
|
|
234
|
+
else AIChatError
|
|
235
|
+
)
|
|
236
|
+
raise exc_type(code, error.get("message", ""))
|
|
237
|
+
result = body.get("result")
|
|
238
|
+
return result if isinstance(result, dict) else {}
|
|
239
|
+
|
|
240
|
+
# ── API methods ──────────────────────────────────────────────────
|
|
241
|
+
|
|
242
|
+
async def create_conversation(
|
|
243
|
+
self,
|
|
244
|
+
conversation_id: str,
|
|
245
|
+
config_url: str,
|
|
246
|
+
user_message: str | None = None,
|
|
247
|
+
timeout: int | None = None,
|
|
248
|
+
user_metadata: dict[str, Any] | None = None,
|
|
249
|
+
reinit: bool = False,
|
|
250
|
+
) -> ConversationInfo:
|
|
251
|
+
"""Create a conversation (or reinitialize an existing one)."""
|
|
252
|
+
params: dict[str, Any] = {"id": conversation_id, "config_url": config_url}
|
|
253
|
+
if user_message:
|
|
254
|
+
params["user_message"] = user_message
|
|
255
|
+
if timeout:
|
|
256
|
+
params["conversation_timeout"] = timeout
|
|
257
|
+
if user_metadata:
|
|
258
|
+
params["user_meta_data"] = user_metadata
|
|
259
|
+
if reinit:
|
|
260
|
+
params["reinit"] = True
|
|
261
|
+
result = await self._request("create_conversation", params)
|
|
262
|
+
return ConversationInfo(
|
|
263
|
+
id=conversation_id,
|
|
264
|
+
status=result.get("status", "created"),
|
|
265
|
+
initial_message=result.get("initial_message"),
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
async def chat(
|
|
269
|
+
self,
|
|
270
|
+
conversation_id: str,
|
|
271
|
+
message: str,
|
|
272
|
+
role: str = "user",
|
|
273
|
+
config_url: str | None = None,
|
|
274
|
+
user_metadata: dict[str, Any] | None = None,
|
|
275
|
+
timeout: int | None = None,
|
|
276
|
+
reinit: bool = False,
|
|
277
|
+
) -> ChatResponse:
|
|
278
|
+
"""Send a message and return the AI reply.
|
|
279
|
+
|
|
280
|
+
This awaits a full LLM round trip server-side — expect seconds.
|
|
281
|
+
Passing ``config_url`` auto-creates the conversation if it doesn't
|
|
282
|
+
exist yet; ``timeout`` and ``reinit`` apply to that auto-create,
|
|
283
|
+
with the same meaning as on :meth:`create_conversation`.
|
|
284
|
+
"""
|
|
285
|
+
params: dict[str, Any] = {
|
|
286
|
+
"id": conversation_id,
|
|
287
|
+
"message": message,
|
|
288
|
+
"role": role,
|
|
289
|
+
}
|
|
290
|
+
if config_url:
|
|
291
|
+
params["config_url"] = config_url
|
|
292
|
+
if user_metadata:
|
|
293
|
+
params["user_meta_data"] = user_metadata
|
|
294
|
+
if timeout:
|
|
295
|
+
params["conversation_timeout"] = timeout
|
|
296
|
+
if reinit:
|
|
297
|
+
params["reinit"] = True
|
|
298
|
+
result = await self._request("chat", params)
|
|
299
|
+
return ChatResponse(
|
|
300
|
+
text=result.get("response", ""),
|
|
301
|
+
conversation_id=conversation_id,
|
|
302
|
+
user_event=result.get("user_event"),
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
async def end(self, conversation_id: str) -> bool:
|
|
306
|
+
"""End a conversation (triggers server-side post-processing)."""
|
|
307
|
+
result = await self._request("end_conversation", {"id": conversation_id})
|
|
308
|
+
return result.get("status") == "ended"
|
|
309
|
+
|
|
310
|
+
async def delete(self, conversation_id: str) -> bool:
|
|
311
|
+
"""Permanently delete a conversation and its data."""
|
|
312
|
+
result = await self._request("delete", {"id": conversation_id})
|
|
313
|
+
return result.get("status") == "deleted"
|
|
314
|
+
|
|
315
|
+
async def log(self, conversation_id: str) -> ChatLog:
|
|
316
|
+
"""Full message history plus the call timeline."""
|
|
317
|
+
result = await self._request("chat_log", {"id": conversation_id})
|
|
318
|
+
return ChatLog(
|
|
319
|
+
messages=result.get("chat_log", []),
|
|
320
|
+
call_timeline=result.get("call_timeline", []),
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
async def summarize(
|
|
324
|
+
self,
|
|
325
|
+
conversation_id: str,
|
|
326
|
+
summary_prompt: str | None = None,
|
|
327
|
+
**sampling: Any,
|
|
328
|
+
) -> str:
|
|
329
|
+
"""AI summary of the conversation (rate limited server-side).
|
|
330
|
+
|
|
331
|
+
Raises :class:`SummaryError` when the server reports that summary
|
|
332
|
+
generation failed — the service returns EXACTLY ONE of ``{summary}`` or
|
|
333
|
+
``{error}`` (both on the success envelope), so a failure must surface as
|
|
334
|
+
an error, never as an empty string.
|
|
335
|
+
"""
|
|
336
|
+
params: dict[str, Any] = {"id": conversation_id}
|
|
337
|
+
if summary_prompt:
|
|
338
|
+
params["summary_prompt"] = summary_prompt
|
|
339
|
+
params.update({k: v for k, v in sampling.items() if v is not None})
|
|
340
|
+
result = await self._request("summarize", params)
|
|
341
|
+
if "error" in result and "summary" not in result:
|
|
342
|
+
raise SummaryError(None, str(result["error"]))
|
|
343
|
+
summary = result.get("summary", "")
|
|
344
|
+
return summary if isinstance(summary, str) else str(summary)
|
|
@@ -20,7 +20,7 @@ class Section(TypedDict, total=False):
|
|
|
20
20
|
main: list[SWMLMethod]
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
SWMLMethod: TypeAlias = "Answer | AI | AmazonBedrock | Cond | Connect | Denoise | EnterQueue | Execute | Goto | Label | LiveTranscribe | LiveTranslate | Hangup | JoinRoom | JoinConference | Play | Prompt | ReceiveFax | Record | RecordCall | Request | Return | SendDigits | SendFax | SendSMS | Set | Sleep | SIPRefer | StopDenoise | StopRecordCall | StopTap | Switch | Tap | Transfer | Unset | Pay | DetectMachine | UserEvent"
|
|
23
|
+
SWMLMethod: TypeAlias = "Answer | AI | AmazonBedrock | Cond | Connect | Denoise | EnterQueue | Execute | Goto | Label | LiveTranscribe | AiSidecar | LiveTranslate | Hangup | JoinRoom | JoinConference | Play | Prompt | ReceiveFax | Record | RecordCall | Request | Return | SendDigits | SendFax | SendSMS | Set | Sleep | SIPRefer | StopDenoise | StopRecordCall | StopTap | Switch | Tap | Transfer | Unset | Pay | DetectMachine | UserEvent"
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
class Answer(TypedDict, total=False):
|
|
@@ -295,7 +295,7 @@ class ConnectDeviceSingle(TypedDict, total=False):
|
|
|
295
295
|
codecs: str
|
|
296
296
|
webrtc_media: bool | SWMLVar
|
|
297
297
|
session_timeout: int | SWMLVar
|
|
298
|
-
ringback: list[str]
|
|
298
|
+
ringback: list[str] | RingbackConfig
|
|
299
299
|
result: ConnectSwitch | list[CondParams]
|
|
300
300
|
timeout: int | SWMLVar
|
|
301
301
|
max_duration: int | SWMLVar
|
|
@@ -319,7 +319,7 @@ class ConnectDeviceSerial(TypedDict, total=False):
|
|
|
319
319
|
codecs: str
|
|
320
320
|
webrtc_media: bool | SWMLVar
|
|
321
321
|
session_timeout: int | SWMLVar
|
|
322
|
-
ringback: list[str]
|
|
322
|
+
ringback: list[str] | RingbackConfig
|
|
323
323
|
result: ConnectSwitch | list[CondParams]
|
|
324
324
|
timeout: int | SWMLVar
|
|
325
325
|
max_duration: int | SWMLVar
|
|
@@ -343,7 +343,7 @@ class ConnectDeviceParallel(TypedDict, total=False):
|
|
|
343
343
|
codecs: str
|
|
344
344
|
webrtc_media: bool | SWMLVar
|
|
345
345
|
session_timeout: int | SWMLVar
|
|
346
|
-
ringback: list[str]
|
|
346
|
+
ringback: list[str] | RingbackConfig
|
|
347
347
|
result: ConnectSwitch | list[CondParams]
|
|
348
348
|
timeout: int | SWMLVar
|
|
349
349
|
max_duration: int | SWMLVar
|
|
@@ -367,7 +367,7 @@ class ConnectDeviceSerialParallel(TypedDict, total=False):
|
|
|
367
367
|
codecs: str
|
|
368
368
|
webrtc_media: bool | SWMLVar
|
|
369
369
|
session_timeout: int | SWMLVar
|
|
370
|
-
ringback: list[str]
|
|
370
|
+
ringback: list[str] | RingbackConfig
|
|
371
371
|
result: ConnectSwitch | list[CondParams]
|
|
372
372
|
timeout: int | SWMLVar
|
|
373
373
|
max_duration: int | SWMLVar
|
|
@@ -1530,6 +1530,30 @@ class UserInputAction(TypedDict, total=False):
|
|
|
1530
1530
|
user_input: str
|
|
1531
1531
|
|
|
1532
1532
|
|
|
1533
|
+
class AiSidecar(TypedDict, total=False):
|
|
1534
|
+
"""Open shape: extra server keys permitted; not validated at runtime."""
|
|
1535
|
+
|
|
1536
|
+
ai_sidecar: dict[str, Any]
|
|
1537
|
+
|
|
1538
|
+
|
|
1539
|
+
class RingbackConfig(TypedDict, total=False):
|
|
1540
|
+
"""Ringback configuration (the modern object form). Declared as a named $defs entry so every generator emits a TYPED shape via $ref rather than collapsing an inline object to an untyped map; the legacy URI array remains the other oneOf branch.
|
|
1541
|
+
|
|
1542
|
+
Open shape: extra server keys are permitted and partial payloads are valid;
|
|
1543
|
+
not validated at runtime (a TypedDict is a plain ``dict``).
|
|
1544
|
+
"""
|
|
1545
|
+
|
|
1546
|
+
url: str
|
|
1547
|
+
urls: list[str]
|
|
1548
|
+
volume: float
|
|
1549
|
+
auto_answer: bool
|
|
1550
|
+
say_voice: str
|
|
1551
|
+
say_language: str
|
|
1552
|
+
say_gender: Literal["male", "female"]
|
|
1553
|
+
status_url: str
|
|
1554
|
+
loop: int
|
|
1555
|
+
|
|
1556
|
+
|
|
1533
1557
|
class ConnectConfig(TypedDict, total=False):
|
|
1534
1558
|
"""Dial a SIP URI or phone number.
|
|
1535
1559
|
|
|
@@ -1542,7 +1566,7 @@ class ConnectConfig(TypedDict, total=False):
|
|
|
1542
1566
|
codecs: str
|
|
1543
1567
|
webrtc_media: bool | SWMLVar
|
|
1544
1568
|
session_timeout: int | SWMLVar
|
|
1545
|
-
ringback: list[str]
|
|
1569
|
+
ringback: list[str] | RingbackConfig
|
|
1546
1570
|
result: ConnectSwitch | list[CondParams]
|
|
1547
1571
|
timeout: int | SWMLVar
|
|
1548
1572
|
max_duration: int | SWMLVar
|
|
@@ -1597,6 +1621,27 @@ class LiveTranscribeConfig(TypedDict, total=False):
|
|
|
1597
1621
|
action: TranscribeAction
|
|
1598
1622
|
|
|
1599
1623
|
|
|
1624
|
+
class AiSidecarConfig(TypedDict, total=False):
|
|
1625
|
+
"""Start ai_sidecar mode — live_transcribe with an LLM/SWAIG/MCP loop on top.
|
|
1626
|
+
|
|
1627
|
+
Open shape: extra server keys are permitted and partial payloads are valid;
|
|
1628
|
+
not validated at runtime (a TypedDict is a plain ``dict``).
|
|
1629
|
+
"""
|
|
1630
|
+
|
|
1631
|
+
prompt: str | dict[str, Any]
|
|
1632
|
+
lang: str
|
|
1633
|
+
model: str
|
|
1634
|
+
direction: list[Literal["remote-caller", "local-caller"]]
|
|
1635
|
+
customer_role: Literal["remote-caller", "local-caller"]
|
|
1636
|
+
url: str
|
|
1637
|
+
SWAIG: SWAIG
|
|
1638
|
+
permissions: dict[str, Any]
|
|
1639
|
+
global_data: dict[str, Any]
|
|
1640
|
+
hints: list[str]
|
|
1641
|
+
params: dict[str, Any]
|
|
1642
|
+
action: dict[str, Any]
|
|
1643
|
+
|
|
1644
|
+
|
|
1600
1645
|
class LiveTranslateConfig(TypedDict, total=False):
|
|
1601
1646
|
"""Start live translation of the call. The translation will be sent to the specified webhook URL.
|
|
1602
1647
|
|
|
@@ -1899,6 +1944,10 @@ class _SwmlVerbs:
|
|
|
1899
1944
|
"""Start live transcription of the call. The transcription will be sent to the specified webhook URL."""
|
|
1900
1945
|
raise NotImplementedError # installed dynamically at runtime
|
|
1901
1946
|
|
|
1947
|
+
def ai_sidecar(self: _Self, config: AiSidecarConfig | None = None) -> _Self:
|
|
1948
|
+
"""Start ai_sidecar mode — live_transcribe with an LLM/SWAIG/MCP loop on top."""
|
|
1949
|
+
raise NotImplementedError # installed dynamically at runtime
|
|
1950
|
+
|
|
1902
1951
|
def live_translate(self: _Self, config: LiveTranslateConfig | None = None) -> _Self:
|
|
1903
1952
|
"""Start live translation of the call. The translation will be sent to the specified webhook URL."""
|
|
1904
1953
|
raise NotImplementedError # installed dynamically at runtime
|