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.
Files changed (231) hide show
  1. {roomkit-0.1.1 → roomkit-0.2.0}/PKG-INFO +10 -1
  2. {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/channels.md +4 -0
  3. {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/index.md +7 -5
  4. roomkit-0.2.0/docs/api/providers-rcs.md +25 -0
  5. roomkit-0.2.0/docs/api/providers-voice.md +56 -0
  6. {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/sources.md +124 -0
  7. {roomkit-0.1.1 → roomkit-0.2.0}/docs/architecture.md +106 -0
  8. roomkit-0.2.0/docs/faq.md +399 -0
  9. {roomkit-0.1.1 → roomkit-0.2.0}/docs/features.md +199 -20
  10. {roomkit-0.1.1 → roomkit-0.2.0}/docs/roomkit-rfc.md +748 -5
  11. {roomkit-0.1.1 → roomkit-0.2.0}/docs/technical.md +149 -5
  12. {roomkit-0.1.1 → roomkit-0.2.0}/pyproject.toml +3 -0
  13. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/__init__.py +45 -0
  14. roomkit-0.2.0/src/roomkit/_version.py +1 -0
  15. roomkit-0.2.0/src/roomkit/channels/voice.py +728 -0
  16. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/_channel_ops.py +7 -0
  17. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/_inbound.py +4 -0
  18. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/framework.py +177 -1
  19. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/hooks.py +32 -6
  20. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/models/enums.py +12 -0
  21. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/sources/__init__.py +4 -4
  22. roomkit-0.2.0/src/roomkit/sources/sse.py +226 -0
  23. roomkit-0.2.0/src/roomkit/voice/__init__.py +99 -0
  24. roomkit-0.2.0/src/roomkit/voice/backends/__init__.py +1 -0
  25. roomkit-0.2.0/src/roomkit/voice/backends/base.py +264 -0
  26. roomkit-0.2.0/src/roomkit/voice/backends/fastrtc.py +467 -0
  27. roomkit-0.2.0/src/roomkit/voice/backends/mock.py +302 -0
  28. roomkit-0.2.0/src/roomkit/voice/base.py +115 -0
  29. roomkit-0.2.0/src/roomkit/voice/events.py +140 -0
  30. roomkit-0.2.0/src/roomkit/voice/stt/__init__.py +1 -0
  31. roomkit-0.2.0/src/roomkit/voice/stt/base.py +58 -0
  32. roomkit-0.2.0/src/roomkit/voice/stt/deepgram.py +214 -0
  33. roomkit-0.2.0/src/roomkit/voice/stt/mock.py +40 -0
  34. roomkit-0.2.0/src/roomkit/voice/tts/__init__.py +1 -0
  35. roomkit-0.2.0/src/roomkit/voice/tts/base.py +58 -0
  36. roomkit-0.2.0/src/roomkit/voice/tts/elevenlabs.py +329 -0
  37. roomkit-0.2.0/src/roomkit/voice/tts/mock.py +51 -0
  38. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_enums.py +1 -1
  39. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_framework.py +23 -0
  40. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_public_api.py +1 -1
  41. roomkit-0.2.0/tests/test_sources_sse.py +588 -0
  42. roomkit-0.2.0/tests/test_voice.py +812 -0
  43. roomkit-0.2.0/tests/test_voice_fastrtc.py +458 -0
  44. roomkit-0.2.0/tests/test_voice_integration.py +979 -0
  45. roomkit-0.1.1/src/roomkit/_version.py +0 -1
  46. {roomkit-0.1.1 → roomkit-0.2.0}/.gitignore +0 -0
  47. {roomkit-0.1.1 → roomkit-0.2.0}/AGENTS.md +0 -0
  48. {roomkit-0.1.1 → roomkit-0.2.0}/LICENSE +0 -0
  49. {roomkit-0.1.1 → roomkit-0.2.0}/README.md +0 -0
  50. {roomkit-0.1.1 → roomkit-0.2.0}/docs/ai-integration.md +0 -0
  51. {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/channel-models.md +0 -0
  52. {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/channel.md +0 -0
  53. {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/delivery.md +0 -0
  54. {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/enums.md +0 -0
  55. {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/events.md +0 -0
  56. {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/hook-models.md +0 -0
  57. {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/hooks.md +0 -0
  58. {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/identity.md +0 -0
  59. {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/providers-ai.md +0 -0
  60. {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/providers-email.md +0 -0
  61. {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/providers-http.md +0 -0
  62. {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/providers-messenger.md +0 -0
  63. {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/providers-sms.md +0 -0
  64. {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/providers-whatsapp.md +0 -0
  65. {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/realtime.md +0 -0
  66. {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/room.md +0 -0
  67. {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/roomkit.md +0 -0
  68. {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/routing.md +0 -0
  69. {roomkit-0.1.1 → roomkit-0.2.0}/docs/api/store.md +0 -0
  70. {roomkit-0.1.1 → roomkit-0.2.0}/docs/cpaas-comparison.md +0 -0
  71. {roomkit-0.1.1 → roomkit-0.2.0}/docs/index.md +0 -0
  72. {roomkit-0.1.1 → roomkit-0.2.0}/docs/llms.txt +0 -0
  73. {roomkit-0.1.1 → roomkit-0.2.0}/docs/mcp.md +0 -0
  74. {roomkit-0.1.1 → roomkit-0.2.0}/llms.txt +0 -0
  75. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/ai_docs.py +0 -0
  76. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/channels/__init__.py +0 -0
  77. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/channels/ai.py +0 -0
  78. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/channels/base.py +0 -0
  79. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/channels/transport.py +0 -0
  80. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/channels/websocket.py +0 -0
  81. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/__init__.py +0 -0
  82. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/_helpers.py +0 -0
  83. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/_room_lifecycle.py +0 -0
  84. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/circuit_breaker.py +0 -0
  85. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/event_router.py +0 -0
  86. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/inbound_router.py +0 -0
  87. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/locks.py +0 -0
  88. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/rate_limiter.py +0 -0
  89. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/retry.py +0 -0
  90. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/router.py +0 -0
  91. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/core/transcoder.py +0 -0
  92. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/identity/__init__.py +0 -0
  93. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/identity/base.py +0 -0
  94. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/identity/mock.py +0 -0
  95. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/models/__init__.py +0 -0
  96. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/models/channel.py +0 -0
  97. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/models/context.py +0 -0
  98. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/models/delivery.py +0 -0
  99. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/models/event.py +0 -0
  100. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/models/framework_event.py +0 -0
  101. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/models/hook.py +0 -0
  102. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/models/identity.py +0 -0
  103. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/models/participant.py +0 -0
  104. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/models/room.py +0 -0
  105. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/models/task.py +0 -0
  106. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/__init__.py +0 -0
  107. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/ai/__init__.py +0 -0
  108. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/ai/base.py +0 -0
  109. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/ai/mock.py +0 -0
  110. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/anthropic/__init__.py +0 -0
  111. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/anthropic/ai.py +0 -0
  112. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/anthropic/config.py +0 -0
  113. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/elasticemail/__init__.py +0 -0
  114. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/elasticemail/config.py +0 -0
  115. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/elasticemail/email.py +0 -0
  116. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/email/__init__.py +0 -0
  117. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/email/base.py +0 -0
  118. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/email/mock.py +0 -0
  119. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/gemini/__init__.py +0 -0
  120. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/gemini/ai.py +0 -0
  121. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/gemini/config.py +0 -0
  122. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/http/__init__.py +0 -0
  123. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/http/base.py +0 -0
  124. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/http/config.py +0 -0
  125. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/http/mock.py +0 -0
  126. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/http/provider.py +0 -0
  127. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/http/webhook.py +0 -0
  128. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/messenger/__init__.py +0 -0
  129. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/messenger/base.py +0 -0
  130. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/messenger/config.py +0 -0
  131. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/messenger/facebook.py +0 -0
  132. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/messenger/mock.py +0 -0
  133. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/messenger/webhook.py +0 -0
  134. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/openai/__init__.py +0 -0
  135. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/openai/ai.py +0 -0
  136. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/openai/config.py +0 -0
  137. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/pydantic_ai/__init__.py +0 -0
  138. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/pydantic_ai/config.py +0 -0
  139. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/rcs/__init__.py +0 -0
  140. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/rcs/base.py +0 -0
  141. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/rcs/mock.py +0 -0
  142. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/sendgrid/__init__.py +0 -0
  143. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/sendgrid/config.py +0 -0
  144. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/sinch/__init__.py +0 -0
  145. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/sinch/config.py +0 -0
  146. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/sinch/sms.py +0 -0
  147. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/sms/__init__.py +0 -0
  148. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/sms/base.py +0 -0
  149. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/sms/meta.py +0 -0
  150. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/sms/mock.py +0 -0
  151. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/sms/phone.py +0 -0
  152. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/telnyx/__init__.py +0 -0
  153. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/telnyx/config.py +0 -0
  154. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/telnyx/rcs.py +0 -0
  155. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/telnyx/sms.py +0 -0
  156. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/twilio/__init__.py +0 -0
  157. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/twilio/config.py +0 -0
  158. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/twilio/rcs.py +0 -0
  159. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/twilio/sms.py +0 -0
  160. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/voicemeup/__init__.py +0 -0
  161. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/voicemeup/config.py +0 -0
  162. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/voicemeup/sms.py +0 -0
  163. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/whatsapp/__init__.py +0 -0
  164. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/whatsapp/base.py +0 -0
  165. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/providers/whatsapp/mock.py +0 -0
  166. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/py.typed +0 -0
  167. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/realtime/__init__.py +0 -0
  168. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/realtime/base.py +0 -0
  169. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/realtime/memory.py +0 -0
  170. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/sources/base.py +0 -0
  171. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/sources/websocket.py +0 -0
  172. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/store/__init__.py +0 -0
  173. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/store/base.py +0 -0
  174. {roomkit-0.1.1 → roomkit-0.2.0}/src/roomkit/store/memory.py +0 -0
  175. {roomkit-0.1.1 → roomkit-0.2.0}/tests/__init__.py +0 -0
  176. {roomkit-0.1.1 → roomkit-0.2.0}/tests/conftest.py +0 -0
  177. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_ai_docs.py +0 -0
  178. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_channel_abc.py +0 -0
  179. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_channels/__init__.py +0 -0
  180. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_channels/test_ai.py +0 -0
  181. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_channels/test_email.py +0 -0
  182. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_channels/test_http.py +0 -0
  183. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_channels/test_messenger.py +0 -0
  184. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_channels/test_sms.py +0 -0
  185. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_channels/test_websocket.py +0 -0
  186. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_channels/test_whatsapp.py +0 -0
  187. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_circuit_breaker.py +0 -0
  188. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_configs.py +0 -0
  189. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_framework_events.py +0 -0
  190. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_framework_queries.py +0 -0
  191. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_hook_side_effects.py +0 -0
  192. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_hooks.py +0 -0
  193. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_identity_hooks.py +0 -0
  194. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_identity_pipeline.py +0 -0
  195. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_inbound_routing.py +0 -0
  196. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_integration/__init__.py +0 -0
  197. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_integration/test_ai_assistant.py +0 -0
  198. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_integration/test_ai_chain_depth.py +0 -0
  199. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_integration/test_cross_channel.py +0 -0
  200. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_integration/test_dynamic_channels.py +0 -0
  201. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_integration/test_human_ai.py +0 -0
  202. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_integration/test_identity_resolution.py +0 -0
  203. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_integration/test_observer.py +0 -0
  204. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_integration/test_sin_scanning.py +0 -0
  205. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_lifecycle_hooks.py +0 -0
  206. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_locks.py +0 -0
  207. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_mock_providers.py +0 -0
  208. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_models.py +0 -0
  209. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_observability.py +0 -0
  210. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/__init__.py +0 -0
  211. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_anthropic.py +0 -0
  212. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_elasticemail.py +0 -0
  213. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_gemini.py +0 -0
  214. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_http.py +0 -0
  215. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_messenger.py +0 -0
  216. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_openai.py +0 -0
  217. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_phone.py +0 -0
  218. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_rcs.py +0 -0
  219. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_sinch.py +0 -0
  220. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_sms_utils.py +0 -0
  221. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_telnyx.py +0 -0
  222. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_telnyx_rcs.py +0 -0
  223. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_twilio.py +0 -0
  224. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_providers/test_voicemeup.py +0 -0
  225. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_realtime.py +0 -0
  226. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_resilience.py +0 -0
  227. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_router.py +0 -0
  228. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_sources.py +0 -0
  229. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_sources_websocket.py +0 -0
  230. {roomkit-0.1.1 → roomkit-0.2.0}/tests/test_store_memory.py +0 -0
  231. {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.1.1
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
@@ -2,12 +2,16 @@
2
2
 
3
3
  ::: roomkit.SMSChannel
4
4
 
5
+ ::: roomkit.RCSChannel
6
+
5
7
  ::: roomkit.EmailChannel
6
8
 
7
9
  ::: roomkit.AIChannel
8
10
 
9
11
  ::: roomkit.WebSocketChannel
10
12
 
13
+ ::: roomkit.VoiceChannel
14
+
11
15
  ::: roomkit.WhatsAppChannel
12
16
 
13
17
  ::: roomkit.MessengerChannel
@@ -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
- - **[Email](providers-email.md)** — EmailProvider
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 |