roomkit 0.1.1__tar.gz → 0.2.0__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.
- {roomkit-0.1.1 → roomkit-0.2.0}/PKG-INFO +10 -1
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/channels.md +4 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/index.md +7 -5
- roomkit-0.2.0/docs/api/providers-rcs.md +25 -0
- roomkit-0.2.0/docs/api/providers-voice.md +56 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/sources.md +124 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/architecture.md +106 -0
- roomkit-0.2.0/docs/faq.md +399 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/features.md +199 -20
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/roomkit-rfc.md +748 -5
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/technical.md +149 -5
- {roomkit-0.1.1 → roomkit-0.2.0}/pyproject.toml +3 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/__init__.py +45 -0
- roomkit-0.2.0/src/roomkit/_version.py +1 -0
- roomkit-0.2.0/src/roomkit/channels/voice.py +728 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/_channel_ops.py +7 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/_inbound.py +4 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/framework.py +177 -1
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/hooks.py +32 -6
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/models/enums.py +12 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/sources/__init__.py +4 -4
- roomkit-0.2.0/src/roomkit/sources/sse.py +226 -0
- roomkit-0.2.0/src/roomkit/voice/__init__.py +99 -0
- roomkit-0.2.0/src/roomkit/voice/backends/__init__.py +1 -0
- roomkit-0.2.0/src/roomkit/voice/backends/base.py +264 -0
- roomkit-0.2.0/src/roomkit/voice/backends/fastrtc.py +467 -0
- roomkit-0.2.0/src/roomkit/voice/backends/mock.py +302 -0
- roomkit-0.2.0/src/roomkit/voice/base.py +115 -0
- roomkit-0.2.0/src/roomkit/voice/events.py +140 -0
- roomkit-0.2.0/src/roomkit/voice/stt/__init__.py +1 -0
- roomkit-0.2.0/src/roomkit/voice/stt/base.py +58 -0
- roomkit-0.2.0/src/roomkit/voice/stt/deepgram.py +214 -0
- roomkit-0.2.0/src/roomkit/voice/stt/mock.py +40 -0
- roomkit-0.2.0/src/roomkit/voice/tts/__init__.py +1 -0
- roomkit-0.2.0/src/roomkit/voice/tts/base.py +58 -0
- roomkit-0.2.0/src/roomkit/voice/tts/elevenlabs.py +329 -0
- roomkit-0.2.0/src/roomkit/voice/tts/mock.py +51 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_enums.py +1 -1
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_framework.py +23 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_public_api.py +1 -1
- roomkit-0.2.0/tests/test_sources_sse.py +588 -0
- roomkit-0.2.0/tests/test_voice.py +812 -0
- roomkit-0.2.0/tests/test_voice_fastrtc.py +458 -0
- roomkit-0.2.0/tests/test_voice_integration.py +979 -0
- roomkit-0.1.1/src/roomkit/_version.py +0 -1
- {roomkit-0.1.1 → roomkit-0.2.0}/.gitignore +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/AGENTS.md +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/LICENSE +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/README.md +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/ai-integration.md +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/channel-models.md +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/channel.md +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/delivery.md +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/enums.md +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/events.md +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/hook-models.md +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/hooks.md +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/identity.md +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/providers-ai.md +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/providers-email.md +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/providers-http.md +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/providers-messenger.md +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/providers-sms.md +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/providers-whatsapp.md +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/realtime.md +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/room.md +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/roomkit.md +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/routing.md +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/store.md +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/cpaas-comparison.md +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/index.md +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/llms.txt +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/docs/mcp.md +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/llms.txt +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/ai_docs.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/channels/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/channels/ai.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/channels/base.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/channels/transport.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/channels/websocket.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/_helpers.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/_room_lifecycle.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/circuit_breaker.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/event_router.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/inbound_router.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/locks.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/rate_limiter.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/retry.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/router.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/transcoder.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/identity/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/identity/base.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/identity/mock.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/models/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/models/channel.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/models/context.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/models/delivery.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/models/event.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/models/framework_event.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/models/hook.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/models/identity.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/models/participant.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/models/room.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/models/task.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/ai/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/ai/base.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/ai/mock.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/anthropic/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/anthropic/ai.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/anthropic/config.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/elasticemail/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/elasticemail/config.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/elasticemail/email.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/email/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/email/base.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/email/mock.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/gemini/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/gemini/ai.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/gemini/config.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/http/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/http/base.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/http/config.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/http/mock.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/http/provider.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/http/webhook.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/messenger/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/messenger/base.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/messenger/config.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/messenger/facebook.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/messenger/mock.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/messenger/webhook.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/openai/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/openai/ai.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/openai/config.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/pydantic_ai/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/pydantic_ai/config.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/rcs/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/rcs/base.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/rcs/mock.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/sendgrid/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/sendgrid/config.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/sinch/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/sinch/config.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/sinch/sms.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/sms/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/sms/base.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/sms/meta.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/sms/mock.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/sms/phone.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/telnyx/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/telnyx/config.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/telnyx/rcs.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/telnyx/sms.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/twilio/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/twilio/config.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/twilio/rcs.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/twilio/sms.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/voicemeup/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/voicemeup/config.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/voicemeup/sms.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/whatsapp/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/whatsapp/base.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/whatsapp/mock.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/py.typed +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/realtime/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/realtime/base.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/realtime/memory.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/sources/base.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/sources/websocket.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/store/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/store/base.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/store/memory.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/conftest.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_ai_docs.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_channel_abc.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_channels/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_channels/test_ai.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_channels/test_email.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_channels/test_http.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_channels/test_messenger.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_channels/test_sms.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_channels/test_websocket.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_channels/test_whatsapp.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_circuit_breaker.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_configs.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_framework_events.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_framework_queries.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_hook_side_effects.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_hooks.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_identity_hooks.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_identity_pipeline.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_inbound_routing.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_integration/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_integration/test_ai_assistant.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_integration/test_ai_chain_depth.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_integration/test_cross_channel.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_integration/test_dynamic_channels.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_integration/test_human_ai.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_integration/test_identity_resolution.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_integration/test_observer.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_integration/test_sin_scanning.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_lifecycle_hooks.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_locks.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_mock_providers.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_models.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_observability.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/__init__.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_anthropic.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_elasticemail.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_gemini.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_http.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_messenger.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_openai.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_phone.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_rcs.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_sinch.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_sms_utils.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_telnyx.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_telnyx_rcs.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_twilio.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_voicemeup.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_realtime.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_resilience.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_router.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_sources.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_sources_websocket.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_store_memory.py +0 -0
- {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_websocket_lifecycle.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: roomkit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Pure async Python library for multi-channel conversations
|
|
5
5
|
Project-URL: Homepage, https://roomkit.live
|
|
6
6
|
Project-URL: Repository, https://github.com/sboily/roomkit
|
|
@@ -30,6 +30,7 @@ Requires-Dist: anthropic>=0.30; extra == 'anthropic'
|
|
|
30
30
|
Provides-Extra: dev
|
|
31
31
|
Requires-Dist: anthropic>=0.30; extra == 'dev'
|
|
32
32
|
Requires-Dist: google-genai>=1.0.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: httpx-sse>=0.4; extra == 'dev'
|
|
33
34
|
Requires-Dist: httpx>=0.27; extra == 'dev'
|
|
34
35
|
Requires-Dist: mkdocs-material>=9.5; extra == 'dev'
|
|
35
36
|
Requires-Dist: mkdocs>=1.6; extra == 'dev'
|
|
@@ -49,6 +50,9 @@ Provides-Extra: docs
|
|
|
49
50
|
Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
|
|
50
51
|
Requires-Dist: mkdocs>=1.6; extra == 'docs'
|
|
51
52
|
Requires-Dist: mkdocstrings[python]>=0.27; extra == 'docs'
|
|
53
|
+
Provides-Extra: fastrtc
|
|
54
|
+
Requires-Dist: fastrtc; extra == 'fastrtc'
|
|
55
|
+
Requires-Dist: numpy; extra == 'fastrtc'
|
|
52
56
|
Provides-Extra: gemini
|
|
53
57
|
Requires-Dist: google-genai>=1.0.0; extra == 'gemini'
|
|
54
58
|
Provides-Extra: httpx
|
|
@@ -68,7 +72,12 @@ Requires-Dist: pydantic-ai>=0.1; extra == 'pydantic-ai'
|
|
|
68
72
|
Provides-Extra: pynacl
|
|
69
73
|
Requires-Dist: pynacl>=1.5; extra == 'pynacl'
|
|
70
74
|
Provides-Extra: sources
|
|
75
|
+
Requires-Dist: httpx-sse>=0.4; extra == 'sources'
|
|
76
|
+
Requires-Dist: httpx>=0.27; extra == 'sources'
|
|
71
77
|
Requires-Dist: websockets>=13.0; extra == 'sources'
|
|
78
|
+
Provides-Extra: sse
|
|
79
|
+
Requires-Dist: httpx-sse>=0.4; extra == 'sse'
|
|
80
|
+
Requires-Dist: httpx>=0.27; extra == 'sse'
|
|
72
81
|
Provides-Extra: twilio
|
|
73
82
|
Requires-Dist: twilio>=9.0; extra == 'twilio'
|
|
74
83
|
Provides-Extra: websocket
|
|
@@ -14,7 +14,8 @@ Full auto-generated reference for the `roomkit` public API.
|
|
|
14
14
|
## Channels
|
|
15
15
|
|
|
16
16
|
- **[Channel ABC](channel.md)** — Base class for all channels
|
|
17
|
-
- **[Built-in Channels](channels.md)** — SMS, Email, AI, WebSocket, WhatsApp, Messenger, HTTP
|
|
17
|
+
- **[Built-in Channels](channels.md)** — SMS, RCS, Email, AI, WebSocket, Voice, WhatsApp, Messenger, HTTP
|
|
18
|
+
- **[Voice Channel](providers-voice.md)** — VoiceBackend, STTProvider, TTSProvider, voice events
|
|
18
19
|
|
|
19
20
|
## Models
|
|
20
21
|
|
|
@@ -29,8 +30,9 @@ Full auto-generated reference for the `roomkit` public API.
|
|
|
29
30
|
## Providers
|
|
30
31
|
|
|
31
32
|
- **[AI](providers-ai.md)** — AIProvider, AIContext, AIResponse
|
|
32
|
-
- **[SMS](providers-sms.md)** — SMSProvider
|
|
33
|
-
- **[
|
|
33
|
+
- **[SMS](providers-sms.md)** — SMSProvider, Sinch, Telnyx, Twilio, VoiceMeUp
|
|
34
|
+
- **[RCS](providers-rcs.md)** — RCSProvider, Telnyx RCS, Twilio RCS
|
|
35
|
+
- **[Email](providers-email.md)** — EmailProvider, ElasticEmail
|
|
34
36
|
- **[WhatsApp](providers-whatsapp.md)** — WhatsAppProvider
|
|
35
|
-
- **[Messenger](providers-messenger.md)** — MessengerProvider
|
|
36
|
-
- **[HTTP](providers-http.md)** — HTTPProvider
|
|
37
|
+
- **[Messenger](providers-messenger.md)** — MessengerProvider, Facebook
|
|
38
|
+
- **[HTTP](providers-http.md)** — HTTPProvider, Webhook
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# RCS Providers
|
|
2
|
+
|
|
3
|
+
## Base Classes
|
|
4
|
+
|
|
5
|
+
::: roomkit.RCSProvider
|
|
6
|
+
|
|
7
|
+
::: roomkit.RCSDeliveryResult
|
|
8
|
+
|
|
9
|
+
::: roomkit.MockRCSProvider
|
|
10
|
+
|
|
11
|
+
## Telnyx
|
|
12
|
+
|
|
13
|
+
::: roomkit.TelnyxRCSProvider
|
|
14
|
+
|
|
15
|
+
::: roomkit.TelnyxRCSConfig
|
|
16
|
+
|
|
17
|
+
::: roomkit.parse_telnyx_rcs_webhook
|
|
18
|
+
|
|
19
|
+
## Twilio
|
|
20
|
+
|
|
21
|
+
::: roomkit.TwilioRCSProvider
|
|
22
|
+
|
|
23
|
+
::: roomkit.TwilioRCSConfig
|
|
24
|
+
|
|
25
|
+
::: roomkit.parse_twilio_rcs_webhook
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Voice Providers
|
|
2
|
+
|
|
3
|
+
## Voice Backend
|
|
4
|
+
|
|
5
|
+
::: roomkit.voice.backends.base.VoiceBackend
|
|
6
|
+
|
|
7
|
+
::: roomkit.VoiceCapability
|
|
8
|
+
|
|
9
|
+
::: roomkit.VoiceSession
|
|
10
|
+
|
|
11
|
+
::: roomkit.VoiceSessionState
|
|
12
|
+
|
|
13
|
+
::: roomkit.AudioChunk
|
|
14
|
+
|
|
15
|
+
::: roomkit.TranscriptionResult
|
|
16
|
+
|
|
17
|
+
## STT (Speech-to-Text)
|
|
18
|
+
|
|
19
|
+
::: roomkit.voice.stt.base.STTProvider
|
|
20
|
+
|
|
21
|
+
::: roomkit.voice.stt.mock.MockSTTProvider
|
|
22
|
+
|
|
23
|
+
## TTS (Text-to-Speech)
|
|
24
|
+
|
|
25
|
+
::: roomkit.voice.tts.base.TTSProvider
|
|
26
|
+
|
|
27
|
+
::: roomkit.voice.tts.mock.MockTTSProvider
|
|
28
|
+
|
|
29
|
+
## Mock Voice Backend
|
|
30
|
+
|
|
31
|
+
::: roomkit.voice.backends.mock.MockVoiceBackend
|
|
32
|
+
|
|
33
|
+
::: roomkit.voice.backends.mock.MockVoiceCall
|
|
34
|
+
|
|
35
|
+
## Voice Events
|
|
36
|
+
|
|
37
|
+
::: roomkit.BargeInEvent
|
|
38
|
+
|
|
39
|
+
::: roomkit.TTSCancelledEvent
|
|
40
|
+
|
|
41
|
+
::: roomkit.PartialTranscriptionEvent
|
|
42
|
+
|
|
43
|
+
::: roomkit.VADSilenceEvent
|
|
44
|
+
|
|
45
|
+
::: roomkit.VADAudioLevelEvent
|
|
46
|
+
|
|
47
|
+
## Callback Types
|
|
48
|
+
|
|
49
|
+
| Callback | Signature |
|
|
50
|
+
|----------|-----------|
|
|
51
|
+
| `SpeechStartCallback` | `(VoiceSession) -> Any` |
|
|
52
|
+
| `SpeechEndCallback` | `(VoiceSession, bytes) -> Any` |
|
|
53
|
+
| `PartialTranscriptionCallback` | `(VoiceSession, str, float, bool) -> Any` |
|
|
54
|
+
| `VADSilenceCallback` | `(VoiceSession, int) -> Any` |
|
|
55
|
+
| `VADAudioLevelCallback` | `(VoiceSession, float, bool) -> Any` |
|
|
56
|
+
| `BargeInCallback` | `(VoiceSession) -> Any` |
|
|
@@ -266,6 +266,130 @@ WebSocketSource requires the `websockets` package:
|
|
|
266
266
|
pip install roomkit[websocket]
|
|
267
267
|
```
|
|
268
268
|
|
|
269
|
+
### SSESource
|
|
270
|
+
|
|
271
|
+
Connect to a Server-Sent Events (SSE) endpoint and receive real-time updates:
|
|
272
|
+
|
|
273
|
+
```python
|
|
274
|
+
from roomkit import RoomKit
|
|
275
|
+
from roomkit.sources import SSESource
|
|
276
|
+
|
|
277
|
+
# Basic usage with default JSON parser
|
|
278
|
+
source = SSESource(
|
|
279
|
+
url="https://api.example.com/events",
|
|
280
|
+
channel_id="sse-events",
|
|
281
|
+
)
|
|
282
|
+
await kit.attach_source("sse-events", source)
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
The default parser expects SSE `data` fields to contain JSON:
|
|
286
|
+
|
|
287
|
+
```json
|
|
288
|
+
{
|
|
289
|
+
"sender_id": "user123",
|
|
290
|
+
"text": "Hello world",
|
|
291
|
+
"external_id": "msg-456",
|
|
292
|
+
"metadata": {"key": "value"}
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
Supported event types: `message`, `msg`, `chat`, or empty (default). Other event types (e.g., `ping`, `heartbeat`) are skipped.
|
|
297
|
+
|
|
298
|
+
#### Custom SSE Parser
|
|
299
|
+
|
|
300
|
+
For custom SSE formats, provide a parser function that receives the event type, data, and optional event ID:
|
|
301
|
+
|
|
302
|
+
```python
|
|
303
|
+
from roomkit import InboundMessage, TextContent
|
|
304
|
+
|
|
305
|
+
def my_parser(event: str, data: str, event_id: str | None) -> InboundMessage | None:
|
|
306
|
+
"""Parse custom SSE events."""
|
|
307
|
+
if event != "chat":
|
|
308
|
+
return None # Only process 'chat' events
|
|
309
|
+
|
|
310
|
+
# Parse custom format: "user:message"
|
|
311
|
+
parts = data.split(":", 1)
|
|
312
|
+
if len(parts) < 2:
|
|
313
|
+
return None
|
|
314
|
+
|
|
315
|
+
return InboundMessage(
|
|
316
|
+
channel_id="sse-chat",
|
|
317
|
+
sender_id=parts[0],
|
|
318
|
+
content=TextContent(body=parts[1]),
|
|
319
|
+
external_id=event_id,
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
source = SSESource(
|
|
323
|
+
url="https://stream.example.com/chat",
|
|
324
|
+
channel_id="sse-chat",
|
|
325
|
+
parser=my_parser,
|
|
326
|
+
)
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
#### SSESource Options
|
|
330
|
+
|
|
331
|
+
| Parameter | Type | Default | Description |
|
|
332
|
+
|-----------|------|---------|-------------|
|
|
333
|
+
| `url` | `str` | required | SSE endpoint URL |
|
|
334
|
+
| `channel_id` | `str` | required | Channel ID for emitted messages |
|
|
335
|
+
| `parser` | `Callable` | JSON parser | Function to parse SSE events: `(event, data, id) -> InboundMessage` |
|
|
336
|
+
| `headers` | `dict[str, str]` | `None` | HTTP headers (e.g., Authorization) |
|
|
337
|
+
| `params` | `dict[str, str]` | `None` | Query parameters for the URL |
|
|
338
|
+
| `timeout` | `float` | `30.0` | Connection timeout in seconds |
|
|
339
|
+
| `last_event_id` | `str` | `None` | Resume from this event ID (sent as `Last-Event-ID` header) |
|
|
340
|
+
|
|
341
|
+
#### Resuming from Last Event ID
|
|
342
|
+
|
|
343
|
+
SSE supports resumption via the `Last-Event-ID` header. SSESource tracks the last received event ID automatically:
|
|
344
|
+
|
|
345
|
+
```python
|
|
346
|
+
# Initial connection
|
|
347
|
+
source = SSESource(
|
|
348
|
+
url="https://api.example.com/events",
|
|
349
|
+
channel_id="sse-events",
|
|
350
|
+
)
|
|
351
|
+
await kit.attach_source("sse-events", source)
|
|
352
|
+
|
|
353
|
+
# ... connection drops ...
|
|
354
|
+
|
|
355
|
+
# Get the last event ID for resumption
|
|
356
|
+
last_id = source.last_event_id
|
|
357
|
+
print(f"Last received event: {last_id}")
|
|
358
|
+
|
|
359
|
+
# Create new source that resumes from last position
|
|
360
|
+
resumed_source = SSESource(
|
|
361
|
+
url="https://api.example.com/events",
|
|
362
|
+
channel_id="sse-events",
|
|
363
|
+
last_event_id=last_id,
|
|
364
|
+
)
|
|
365
|
+
await kit.attach_source("sse-events", resumed_source)
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
When `auto_restart=True` (default), RoomKit automatically handles reconnection and uses the tracked `last_event_id` for seamless resumption.
|
|
369
|
+
|
|
370
|
+
#### Authentication
|
|
371
|
+
|
|
372
|
+
Pass authentication via headers:
|
|
373
|
+
|
|
374
|
+
```python
|
|
375
|
+
source = SSESource(
|
|
376
|
+
url="https://api.example.com/events",
|
|
377
|
+
channel_id="sse-events",
|
|
378
|
+
headers={
|
|
379
|
+
"Authorization": "Bearer your-token-here",
|
|
380
|
+
"X-API-Key": "your-api-key",
|
|
381
|
+
},
|
|
382
|
+
)
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
#### Installation
|
|
386
|
+
|
|
387
|
+
SSESource requires `httpx` and `httpx-sse`:
|
|
388
|
+
|
|
389
|
+
```bash
|
|
390
|
+
pip install roomkit[sse]
|
|
391
|
+
```
|
|
392
|
+
|
|
269
393
|
## Implementing a Custom Source
|
|
270
394
|
|
|
271
395
|
Extend `SourceProvider` or `BaseSourceProvider` to create custom sources:
|
|
@@ -17,6 +17,9 @@ graph TB
|
|
|
17
17
|
WA_EXT["WhatsApp"]
|
|
18
18
|
HTTP_EXT["HTTP Webhooks"]
|
|
19
19
|
AI_EXT["AI APIs (Anthropic, OpenAI, Gemini)"]
|
|
20
|
+
VOICE_EXT["Voice Clients (FastRTC / WebRTC)"]
|
|
21
|
+
STT_EXT["STT (Deepgram)"]
|
|
22
|
+
TTS_EXT["TTS (ElevenLabs)"]
|
|
20
23
|
end
|
|
21
24
|
|
|
22
25
|
subgraph RoomKit["RoomKit Orchestrator"]
|
|
@@ -40,6 +43,13 @@ graph TB
|
|
|
40
43
|
WA_CH["WhatsAppChannel"]
|
|
41
44
|
HTTP_CH["HTTPChannel"]
|
|
42
45
|
AI_CH["AIChannel"]
|
|
46
|
+
VOICE_CH["VoiceChannel"]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
subgraph VoiceStack["Voice Stack"]
|
|
50
|
+
VB["VoiceBackend (FastRTC)"]
|
|
51
|
+
STT["STTProvider (Deepgram)"]
|
|
52
|
+
TTS["TTSProvider (ElevenLabs)"]
|
|
43
53
|
end
|
|
44
54
|
|
|
45
55
|
subgraph Storage["Storage Layer"]
|
|
@@ -55,6 +65,7 @@ graph TB
|
|
|
55
65
|
WA_EXT --> WA_CH
|
|
56
66
|
HTTP_EXT --> HTTP_CH
|
|
57
67
|
AI_EXT --> AI_CH
|
|
68
|
+
VOICE_EXT --> VB
|
|
58
69
|
|
|
59
70
|
WS_CH --> IR
|
|
60
71
|
SMS_CH --> IR
|
|
@@ -62,6 +73,7 @@ graph TB
|
|
|
62
73
|
EMAIL_CH --> IR
|
|
63
74
|
MSG_CH --> IR
|
|
64
75
|
HTTP_CH --> IR
|
|
76
|
+
VOICE_CH --> IR
|
|
65
77
|
|
|
66
78
|
IR --> IP
|
|
67
79
|
IP --> HE
|
|
@@ -78,6 +90,7 @@ graph TB
|
|
|
78
90
|
ER --> WA_CH
|
|
79
91
|
ER --> HTTP_CH
|
|
80
92
|
ER --> AI_CH
|
|
93
|
+
ER --> VOICE_CH
|
|
81
94
|
|
|
82
95
|
HE --> STORE
|
|
83
96
|
ER --> STORE
|
|
@@ -85,6 +98,13 @@ graph TB
|
|
|
85
98
|
|
|
86
99
|
WS_CH -.-> RT
|
|
87
100
|
RT -.-> WS_CH
|
|
101
|
+
|
|
102
|
+
VOICE_CH --> VB
|
|
103
|
+
VOICE_CH --> STT
|
|
104
|
+
VOICE_CH --> TTS
|
|
105
|
+
VB --> VOICE_EXT
|
|
106
|
+
STT --> STT_EXT
|
|
107
|
+
TTS --> TTS_EXT
|
|
88
108
|
```
|
|
89
109
|
|
|
90
110
|
---
|
|
@@ -135,9 +155,42 @@ All transport channels (SMS, RCS, Email, WhatsApp, Messenger, HTTP) use the unif
|
|
|
135
155
|
| `WhatsAppChannel` | Transport | `WhatsAppChannel()` factory | WhatsApp Business (mock only) |
|
|
136
156
|
| `HTTPChannel` | Transport | `HTTPChannel()` factory | Generic webhook |
|
|
137
157
|
| `AIChannel` | Intelligence | Direct class | Anthropic Claude, OpenAI GPT, Google Gemini |
|
|
158
|
+
| `VoiceChannel` | Transport | Direct class | FastRTC backend + Deepgram STT + ElevenLabs TTS |
|
|
138
159
|
|
|
139
160
|
The `TransportChannel` class is data-driven: it reads a `recipient_key` from binding metadata for the delivery address, and passes configurable `defaults` to the provider's `send()` method. This eliminates the need for per-channel subclasses.
|
|
140
161
|
|
|
162
|
+
### Voice Stack
|
|
163
|
+
|
|
164
|
+
The voice subsystem provides real-time audio support via three pluggable abstractions:
|
|
165
|
+
|
|
166
|
+
| Component | ABC | Implementations | Responsibility |
|
|
167
|
+
|---|---|---|---|
|
|
168
|
+
| **VoiceBackend** | `voice/base.py` | `FastRTCVoiceBackend` (FastRTC WebSocket), `MockVoiceBackend` | Audio transport: WebSocket/WebRTC connections, VAD callbacks, session management, audio streaming |
|
|
169
|
+
| **STTProvider** | `voice/stt.py` | `DeepgramSTTProvider`, `MockSTTProvider` | Speech-to-text: transcribe audio chunks or streams to text |
|
|
170
|
+
| **TTSProvider** | `voice/tts.py` | `ElevenLabsTTSProvider`, `MockTTSProvider` | Text-to-speech: synthesize text to audio chunks for streaming |
|
|
171
|
+
|
|
172
|
+
The `VoiceChannel` orchestrates the full pipeline:
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
Client audio → VoiceBackend (VAD) → STTProvider → Hook pipeline → process_inbound()
|
|
176
|
+
↓
|
|
177
|
+
Client audio ← VoiceBackend ← TTSProvider ← AI response ← Event broadcast
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**VoiceBackend capabilities** are declared via `VoiceCapability` flags:
|
|
181
|
+
- `INTERRUPTION` -- Backend can cancel ongoing audio playback
|
|
182
|
+
- `PARTIAL_STT` -- Backend provides partial/streaming transcription
|
|
183
|
+
- `VAD_SILENCE` -- Backend emits silence detection events
|
|
184
|
+
- `VAD_AUDIO_LEVEL` -- Backend emits periodic audio level events
|
|
185
|
+
- `BARGE_IN` -- Backend detects user interrupting TTS playback
|
|
186
|
+
|
|
187
|
+
**Voice hook triggers** extend the standard hook system:
|
|
188
|
+
- `ON_SPEECH_START`, `ON_SPEECH_END` -- VAD events
|
|
189
|
+
- `ON_TRANSCRIPTION` -- After STT, sync (can modify or block the text)
|
|
190
|
+
- `BEFORE_TTS`, `AFTER_TTS` -- Around TTS synthesis, sync (can modify text)
|
|
191
|
+
- `ON_BARGE_IN`, `ON_TTS_CANCELLED` -- Interruption events
|
|
192
|
+
- `ON_PARTIAL_TRANSCRIPTION`, `ON_VAD_SILENCE`, `ON_VAD_AUDIO_LEVEL` -- Streaming events
|
|
193
|
+
|
|
141
194
|
### Storage Layer
|
|
142
195
|
|
|
143
196
|
The `ConversationStore` ABC defines the complete persistence interface:
|
|
@@ -273,6 +326,49 @@ flowchart TD
|
|
|
273
326
|
|
|
274
327
|
This ensures AI-to-AI conversations complete atomically within a single `process_inbound` call, bounded by the `max_chain_depth` limit.
|
|
275
328
|
|
|
329
|
+
### Voice Pipeline
|
|
330
|
+
|
|
331
|
+
When a `VoiceChannel` is configured with a backend, STT, and TTS, the full real-time voice pipeline runs:
|
|
332
|
+
|
|
333
|
+
```mermaid
|
|
334
|
+
sequenceDiagram
|
|
335
|
+
participant Client as Voice Client (Browser)
|
|
336
|
+
participant VB as VoiceBackend (FastRTC)
|
|
337
|
+
participant VC as VoiceChannel
|
|
338
|
+
participant STT as STTProvider (Deepgram)
|
|
339
|
+
participant HE as Hook Engine
|
|
340
|
+
participant RK as RoomKit (process_inbound)
|
|
341
|
+
participant AI as AIChannel
|
|
342
|
+
participant TTS as TTSProvider (ElevenLabs)
|
|
343
|
+
|
|
344
|
+
Client->>VB: Audio stream (WebSocket)
|
|
345
|
+
VB->>VB: VAD: detect speech start
|
|
346
|
+
VB->>VC: on_speech_start(session)
|
|
347
|
+
VC->>HE: ON_SPEECH_START hooks
|
|
348
|
+
|
|
349
|
+
VB->>VB: VAD: detect pause (speech end)
|
|
350
|
+
VB->>VC: on_speech_end(session, audio_bytes)
|
|
351
|
+
VC->>HE: ON_SPEECH_END hooks
|
|
352
|
+
VC->>STT: transcribe(audio_chunk)
|
|
353
|
+
STT-->>VC: "Hello, I need help"
|
|
354
|
+
|
|
355
|
+
VC->>VB: send_transcription(session, text, "user")
|
|
356
|
+
VC->>HE: ON_TRANSCRIPTION hooks (sync, can block/modify)
|
|
357
|
+
|
|
358
|
+
VC->>RK: process_inbound(InboundMessage)
|
|
359
|
+
RK->>AI: Event broadcast
|
|
360
|
+
AI-->>RK: AI response text
|
|
361
|
+
|
|
362
|
+
RK->>VC: deliver(event) with AI response
|
|
363
|
+
VC->>HE: BEFORE_TTS hooks (sync, can modify)
|
|
364
|
+
VC->>VB: send_transcription(session, text, "assistant")
|
|
365
|
+
VC->>TTS: synthesize_stream(text)
|
|
366
|
+
TTS-->>VC: AudioChunk stream
|
|
367
|
+
VC->>VB: send_audio(session, stream)
|
|
368
|
+
VB->>Client: mu-law audio (WebSocket)
|
|
369
|
+
VC->>HE: AFTER_TTS hooks
|
|
370
|
+
```
|
|
371
|
+
|
|
276
372
|
---
|
|
277
373
|
|
|
278
374
|
## External Integrations
|
|
@@ -291,6 +387,16 @@ All AI providers support:
|
|
|
291
387
|
- **Function calling / tools** via the `AITool` model
|
|
292
388
|
- **Vision** (Gemini built-in, others configurable via `supports_vision`)
|
|
293
389
|
|
|
390
|
+
### Voice Providers
|
|
391
|
+
|
|
392
|
+
| Provider | SDK | Purpose |
|
|
393
|
+
|---|---|---|
|
|
394
|
+
| Deepgram | `httpx>=0.27`, `websockets>=13.0` | Streaming speech-to-text via `DeepgramSTTProvider` |
|
|
395
|
+
| ElevenLabs | `httpx>=0.27`, `websockets>=13.0` | Text-to-speech synthesis via `ElevenLabsTTSProvider` |
|
|
396
|
+
| FastRTC | `fastrtc`, `numpy` | WebSocket audio transport with VAD via `FastRTCVoiceBackend` |
|
|
397
|
+
|
|
398
|
+
Voice providers use the same **lazy dependency loading** pattern as other providers -- the SDK is imported only when the provider is instantiated. The `roomkit[fastrtc]` optional extra installs FastRTC and NumPy.
|
|
399
|
+
|
|
294
400
|
### Communication Providers
|
|
295
401
|
|
|
296
402
|
| Provider | SDK | Channel | Features |
|