roomkit 0.76.0__tar.gz → 0.78.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 (1275) hide show
  1. {roomkit-0.76.0 → roomkit-0.78.0}/PKG-INFO +1 -1
  2. roomkit-0.78.0/src/roomkit/_version.py +1 -0
  3. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_realtime_audio.py +4 -1
  4. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_realtime_delegation.py +6 -0
  5. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_realtime_tools.py +4 -6
  6. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_realtime_transcription.py +6 -0
  7. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/realtime_voice.py +161 -56
  8. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/voice_ops.py +5 -1
  9. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/live.py +2 -2
  10. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/live_handlers.py +6 -1
  11. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/base.py +13 -0
  12. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/sip_audio.py +7 -0
  13. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/sip_calling.py +2 -0
  14. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/realtime/pacer.py +61 -16
  15. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/realtime/sip_transport.py +6 -0
  16. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/utils.py +15 -0
  17. roomkit-0.78.0/tests/test_live_turn_playback.py +103 -0
  18. roomkit-0.78.0/tests/test_pacer_response_boundary.py +82 -0
  19. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_deepgram.py +35 -2
  20. roomkit-0.78.0/tests/test_realtime_deferred_connection.py +286 -0
  21. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_playback_lifecycle.py +3 -3
  22. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_reasoning.py +6 -1
  23. roomkit-0.76.0/src/roomkit/_version.py +0 -1
  24. {roomkit-0.76.0 → roomkit-0.78.0}/.gitignore +0 -0
  25. {roomkit-0.76.0 → roomkit-0.78.0}/AGENTS.md +0 -0
  26. {roomkit-0.76.0 → roomkit-0.78.0}/LICENSE +0 -0
  27. {roomkit-0.76.0 → roomkit-0.78.0}/README.md +0 -0
  28. {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/__init__.py +0 -0
  29. {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/QUALITY.md +0 -0
  30. {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/README.md +0 -0
  31. {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/__init__.py +0 -0
  32. {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/__main__.py +0 -0
  33. {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/fixtures/quote-policy/SKILL.md +0 -0
  34. {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/fixtures/quote-policy/references/rules.md +0 -0
  35. {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/fixtures/quote-policy/scripts/total.py +0 -0
  36. {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/harness.py +0 -0
  37. {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/measurement.py +0 -0
  38. {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/quality.py +0 -0
  39. {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/quality_oracles.py +0 -0
  40. {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/quality_report.py +0 -0
  41. {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/report.py +0 -0
  42. {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/scenarios.py +0 -0
  43. {roomkit-0.76.0 → roomkit-0.78.0}/docs/README.md +0 -0
  44. {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/acp.md +0 -0
  45. {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/ai-channels.md +0 -0
  46. {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/api-reference.md +0 -0
  47. {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/architecture.md +0 -0
  48. {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/conference.md +0 -0
  49. {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/hooks.md +0 -0
  50. {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/identity-and-realtime.md +0 -0
  51. {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/image-generation.md +0 -0
  52. {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/installation.md +0 -0
  53. {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/ollama-provider.md +0 -0
  54. {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/orchestration.md +0 -0
  55. {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/overview.md +0 -0
  56. {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/quickstart.md +0 -0
  57. {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/realtime-voice.md +0 -0
  58. {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/resilience.md +0 -0
  59. {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/rooms-and-channels.md +0 -0
  60. {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/storage.md +0 -0
  61. {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/testing.md +0 -0
  62. {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/transport-providers.md +0 -0
  63. {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/video.md +0 -0
  64. {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/voice-channels.md +0 -0
  65. {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/voice-pipeline.md +0 -0
  66. {roomkit-0.76.0 → roomkit-0.78.0}/docs/diagrams/architecture.svg +0 -0
  67. {roomkit-0.76.0 → roomkit-0.78.0}/docs/diagrams/avatar-pipeline.svg +0 -0
  68. {roomkit-0.76.0 → roomkit-0.78.0}/docs/diagrams/message-flow.svg +0 -0
  69. {roomkit-0.76.0 → roomkit-0.78.0}/docs/diagrams/orchestration.svg +0 -0
  70. {roomkit-0.76.0 → roomkit-0.78.0}/docs/diagrams/room-lifecycle.svg +0 -0
  71. {roomkit-0.76.0 → roomkit-0.78.0}/docs/diagrams/video-pipeline.svg +0 -0
  72. {roomkit-0.76.0 → roomkit-0.78.0}/docs/diagrams/voice-orchestration.svg +0 -0
  73. {roomkit-0.76.0 → roomkit-0.78.0}/docs/diagrams/voice-pipeline.svg +0 -0
  74. {roomkit-0.76.0 → roomkit-0.78.0}/llms-full.txt +0 -0
  75. {roomkit-0.76.0 → roomkit-0.78.0}/llms.txt +0 -0
  76. {roomkit-0.76.0 → roomkit-0.78.0}/pyproject.toml +0 -0
  77. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/__init__.py +0 -0
  78. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/ai_docs.py +0 -0
  79. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/__init__.py +0 -0
  80. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_acp_client.py +0 -0
  81. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_acp_context.py +0 -0
  82. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_acp_events.py +0 -0
  83. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_acp_usage.py +0 -0
  84. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_ai_coalescers.py +0 -0
  85. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_ai_context.py +0 -0
  86. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_ai_events.py +0 -0
  87. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_ai_generation.py +0 -0
  88. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_ai_loop_rules.py +0 -0
  89. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_ai_policy.py +0 -0
  90. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_ai_resilience.py +0 -0
  91. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_ai_steering.py +0 -0
  92. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_ai_stream_external_tools.py +0 -0
  93. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_ai_stream_round.py +0 -0
  94. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_ai_streaming.py +0 -0
  95. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_ai_tools.py +0 -0
  96. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_cli_markdown.py +0 -0
  97. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_access.py +0 -0
  98. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_activity.py +0 -0
  99. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_attachment.py +0 -0
  100. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_backlog.py +0 -0
  101. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_identity.py +0 -0
  102. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_lane.py +0 -0
  103. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_lanes.py +0 -0
  104. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_metadata.py +0 -0
  105. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_mixer.py +0 -0
  106. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_operations.py +0 -0
  107. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_plug.py +0 -0
  108. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_realtime.py +0 -0
  109. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_recording.py +0 -0
  110. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_recording_events.py +0 -0
  111. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_recording_writer.py +0 -0
  112. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_room_state.py +0 -0
  113. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_roster.py +0 -0
  114. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_session.py +0 -0
  115. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_shutdown.py +0 -0
  116. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_subscription.py +0 -0
  117. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_voice.py +0 -0
  118. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_dangling_recovery.py +0 -0
  119. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_realtime_context.py +0 -0
  120. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_realtime_response.py +0 -0
  121. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_realtime_skills.py +0 -0
  122. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_realtime_speech.py +0 -0
  123. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_realtime_tool_recovery.py +0 -0
  124. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_realtime_tool_search.py +0 -0
  125. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_sandbox_handlers.py +0 -0
  126. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_skill_activation.py +0 -0
  127. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_skill_constants.py +0 -0
  128. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_skill_handlers.py +0 -0
  129. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_speaker.py +0 -0
  130. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_task_planner.py +0 -0
  131. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_tool_eviction.py +0 -0
  132. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_tool_search.py +0 -0
  133. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_tool_search_constants.py +0 -0
  134. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_tool_usage.py +0 -0
  135. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_turn_config.py +0 -0
  136. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_video_hooks.py +0 -0
  137. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_video_resources.py +0 -0
  138. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_voice_hooks.py +0 -0
  139. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_voice_pipeline.py +0 -0
  140. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_voice_stt.py +0 -0
  141. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_voice_tts.py +0 -0
  142. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_voice_turn.py +0 -0
  143. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/acp.py +0 -0
  144. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/acp_transport.py +0 -0
  145. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/agent.py +0 -0
  146. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/ai.py +0 -0
  147. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/av.py +0 -0
  148. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/base.py +0 -0
  149. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/cli.py +0 -0
  150. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/conference.py +0 -0
  151. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/realtime_av.py +0 -0
  152. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/transport.py +0 -0
  153. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/video.py +0 -0
  154. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/voice.py +0 -0
  155. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/websocket.py +0 -0
  156. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/conference/__init__.py +0 -0
  157. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/conference/_livekit_mapping.py +0 -0
  158. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/conference/_livekit_media.py +0 -0
  159. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/conference/_livekit_session.py +0 -0
  160. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/conference/_livekit_voice.py +0 -0
  161. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/conference/_mock_faults.py +0 -0
  162. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/conference/_mock_media.py +0 -0
  163. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/conference/base.py +0 -0
  164. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/conference/livekit.py +0 -0
  165. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/conference/mock.py +0 -0
  166. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/conference/models.py +0 -0
  167. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/console/__init__.py +0 -0
  168. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/console/_activity.py +0 -0
  169. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/console/_brand.py +0 -0
  170. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/console/_chat.py +0 -0
  171. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/console/_display.py +0 -0
  172. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/console/_hooks.py +0 -0
  173. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/console/_shell.py +0 -0
  174. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/console/_state.py +0 -0
  175. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/console/_terminal.py +0 -0
  176. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/console/_tool_preview.py +0 -0
  177. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/__init__.py +0 -0
  178. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/_delivery_targets.py +0 -0
  179. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/_participant_channels.py +0 -0
  180. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/_voice_delivery.py +0 -0
  181. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/callbacks.py +0 -0
  182. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/circuit_breaker.py +0 -0
  183. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/delivery.py +0 -0
  184. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/event_router.py +0 -0
  185. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/exceptions.py +0 -0
  186. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/framework.py +0 -0
  187. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/hooks.py +0 -0
  188. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/inbound_router.py +0 -0
  189. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/lanes.py +0 -0
  190. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/locks.py +0 -0
  191. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/__init__.py +0 -0
  192. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/_child_execution.py +0 -0
  193. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/channel_ops.py +0 -0
  194. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/delegation.py +0 -0
  195. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/deliver.py +0 -0
  196. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/event_ops.py +0 -0
  197. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/greeting.py +0 -0
  198. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/helpers.py +0 -0
  199. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/hooks_api.py +0 -0
  200. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/inbound.py +0 -0
  201. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/inbound_identity.py +0 -0
  202. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/inbound_locked.py +0 -0
  203. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/inbound_streaming.py +0 -0
  204. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/lane_execution.py +0 -0
  205. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/membership.py +0 -0
  206. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/realtime_ops.py +0 -0
  207. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/recording.py +0 -0
  208. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/regenerate.py +0 -0
  209. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/room_lifecycle.py +0 -0
  210. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/source_ops.py +0 -0
  211. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/rate_limiter.py +0 -0
  212. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/retry.py +0 -0
  213. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/router.py +0 -0
  214. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/task_utils.py +0 -0
  215. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/transcoder.py +0 -0
  216. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/visibility.py +0 -0
  217. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/delivery/__init__.py +0 -0
  218. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/delivery/_redis_scripts.py +0 -0
  219. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/delivery/base.py +0 -0
  220. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/delivery/memory.py +0 -0
  221. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/delivery/redis.py +0 -0
  222. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/delivery/serialization.py +0 -0
  223. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/delivery/worker.py +0 -0
  224. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/identity/__init__.py +0 -0
  225. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/identity/base.py +0 -0
  226. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/identity/mock.py +0 -0
  227. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/knowledge/__init__.py +0 -0
  228. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/knowledge/base.py +0 -0
  229. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/knowledge/mock.py +0 -0
  230. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/knowledge/postgres.py +0 -0
  231. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/memory/__init__.py +0 -0
  232. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/memory/_wrapper.py +0 -0
  233. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/memory/base.py +0 -0
  234. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/memory/budget_aware.py +0 -0
  235. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/memory/compacting.py +0 -0
  236. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/memory/mock.py +0 -0
  237. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/memory/retrieval.py +0 -0
  238. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/memory/sliding_window.py +0 -0
  239. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/memory/summarizing.py +0 -0
  240. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/memory/token_estimator.py +0 -0
  241. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/__init__.py +0 -0
  242. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/channel.py +0 -0
  243. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/context.py +0 -0
  244. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/delivery.py +0 -0
  245. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/enums.py +0 -0
  246. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/event.py +0 -0
  247. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/framework_event.py +0 -0
  248. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/hook.py +0 -0
  249. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/identity.py +0 -0
  250. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/participant.py +0 -0
  251. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/pending_input.py +0 -0
  252. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/plan_event.py +0 -0
  253. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/response_metadata.py +0 -0
  254. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/room.py +0 -0
  255. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/session_event.py +0 -0
  256. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/steering.py +0 -0
  257. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/store_filter.py +0 -0
  258. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/streaming.py +0 -0
  259. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/task.py +0 -0
  260. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/thinking_event.py +0 -0
  261. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/tool_call.py +0 -0
  262. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/trace.py +0 -0
  263. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/vision_event.py +0 -0
  264. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/voice_delivery.py +0 -0
  265. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/__init__.py +0 -0
  266. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/base.py +0 -0
  267. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/handoff.py +0 -0
  268. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/pipeline.py +0 -0
  269. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/result.py +0 -0
  270. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/router.py +0 -0
  271. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/session_audit.py +0 -0
  272. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/state.py +0 -0
  273. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/status_bus.py +0 -0
  274. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/status_redis.py +0 -0
  275. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/__init__.py +0 -0
  276. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/loop.py +0 -0
  277. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/pipeline.py +0 -0
  278. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/supervisor/__init__.py +0 -0
  279. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/supervisor/_common.py +0 -0
  280. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/supervisor/_inject_per_worker.py +0 -0
  281. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/supervisor/_inject_strategy.py +0 -0
  282. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/supervisor/_install_auto.py +0 -0
  283. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/supervisor/core.py +0 -0
  284. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/supervisor/delegate.py +0 -0
  285. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/supervisor/execution.py +0 -0
  286. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/supervisor/prompts.py +0 -0
  287. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/supervisor/results.py +0 -0
  288. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/supervisor/supervised.py +0 -0
  289. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/swarm.py +0 -0
  290. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/tool_audit.py +0 -0
  291. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/__init__.py +0 -0
  292. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/ai/__init__.py +0 -0
  293. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/ai/base.py +0 -0
  294. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/ai/image_parts.py +0 -0
  295. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/ai/mock.py +0 -0
  296. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/ai/openai_dialect.py +0 -0
  297. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/anam/__init__.py +0 -0
  298. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/anam/_convert.py +0 -0
  299. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/anam/avatar.py +0 -0
  300. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/anam/config.py +0 -0
  301. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/anam/realtime.py +0 -0
  302. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/anthropic/__init__.py +0 -0
  303. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/anthropic/ai.py +0 -0
  304. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/anthropic/config.py +0 -0
  305. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/anthropic/models.py +0 -0
  306. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/anthropic/request.py +0 -0
  307. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/azure/__init__.py +0 -0
  308. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/azure/ai.py +0 -0
  309. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/azure/config.py +0 -0
  310. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/azure/image.py +0 -0
  311. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/buzz/__init__.py +0 -0
  312. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/buzz/agent.py +0 -0
  313. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/buzz/base.py +0 -0
  314. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/buzz/config.py +0 -0
  315. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/buzz/mock.py +0 -0
  316. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/buzz/relay.py +0 -0
  317. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/cerebras/__init__.py +0 -0
  318. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/cerebras/ai.py +0 -0
  319. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/cerebras/config.py +0 -0
  320. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/cerebras/models.py +0 -0
  321. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/deepgram/__init__.py +0 -0
  322. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/deepgram/config.py +0 -0
  323. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/deepgram/realtime.py +0 -0
  324. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/deepgram/settings.py +0 -0
  325. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/deepgram/voices.py +0 -0
  326. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/deepseek/__init__.py +0 -0
  327. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/deepseek/ai.py +0 -0
  328. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/deepseek/config.py +0 -0
  329. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/deepseek/models.py +0 -0
  330. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/discord/__init__.py +0 -0
  331. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/discord/base.py +0 -0
  332. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/discord/bot.py +0 -0
  333. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/discord/config.py +0 -0
  334. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/discord/mock.py +0 -0
  335. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/elasticemail/__init__.py +0 -0
  336. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/elasticemail/config.py +0 -0
  337. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/elasticemail/email.py +0 -0
  338. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/elevenlabs/__init__.py +0 -0
  339. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/elevenlabs/config.py +0 -0
  340. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/elevenlabs/realtime.py +0 -0
  341. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/elevenlabs/voices.py +0 -0
  342. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/email/__init__.py +0 -0
  343. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/email/base.py +0 -0
  344. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/email/mock.py +0 -0
  345. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/__init__.py +0 -0
  346. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/ai.py +0 -0
  347. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/config.py +0 -0
  348. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/errors.py +0 -0
  349. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/image.py +0 -0
  350. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/image_models.py +0 -0
  351. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/models.py +0 -0
  352. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/realtime.py +0 -0
  353. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/realtime_models.py +0 -0
  354. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/request.py +0 -0
  355. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/schema.py +0 -0
  356. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/sdk.py +0 -0
  357. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/vertex.py +0 -0
  358. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/voices.py +0 -0
  359. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/http/__init__.py +0 -0
  360. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/http/base.py +0 -0
  361. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/http/config.py +0 -0
  362. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/http/mock.py +0 -0
  363. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/http/provider.py +0 -0
  364. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/http/webhook.py +0 -0
  365. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/http_errors.py +0 -0
  366. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/image/__init__.py +0 -0
  367. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/image/base.py +0 -0
  368. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/image/mock.py +0 -0
  369. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/image/options.py +0 -0
  370. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/image/usage.py +0 -0
  371. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/litellm/__init__.py +0 -0
  372. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/litellm/ai.py +0 -0
  373. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/litellm/config.py +0 -0
  374. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/messenger/__init__.py +0 -0
  375. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/messenger/base.py +0 -0
  376. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/messenger/config.py +0 -0
  377. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/messenger/facebook.py +0 -0
  378. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/messenger/mock.py +0 -0
  379. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/messenger/webhook.py +0 -0
  380. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/mistral/__init__.py +0 -0
  381. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/mistral/ai.py +0 -0
  382. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/mistral/config.py +0 -0
  383. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/mistral/models.py +0 -0
  384. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/ollama/__init__.py +0 -0
  385. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/ollama/ai.py +0 -0
  386. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/ollama/config.py +0 -0
  387. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/ollama/models.py +0 -0
  388. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/__init__.py +0 -0
  389. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/ai.py +0 -0
  390. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/config.py +0 -0
  391. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/image.py +0 -0
  392. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/image_models.py +0 -0
  393. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/image_stream.py +0 -0
  394. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/live_client.py +0 -0
  395. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/live_config.py +0 -0
  396. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/live_events.py +0 -0
  397. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/live_hosted.py +0 -0
  398. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/live_models.py +0 -0
  399. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/models.py +0 -0
  400. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/realtime.py +0 -0
  401. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/realtime_base.py +0 -0
  402. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/realtime_events.py +0 -0
  403. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/realtime_models.py +0 -0
  404. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/voices.py +0 -0
  405. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openrouter/__init__.py +0 -0
  406. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openrouter/ai.py +0 -0
  407. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openrouter/config.py +0 -0
  408. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openrouter/image.py +0 -0
  409. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openrouter/image_models.py +0 -0
  410. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openrouter/models.py +0 -0
  411. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/personaplex/__init__.py +0 -0
  412. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/personaplex/config.py +0 -0
  413. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/personaplex/realtime.py +0 -0
  414. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/personaplex/voices.py +0 -0
  415. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/polargrid/__init__.py +0 -0
  416. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/polargrid/ai.py +0 -0
  417. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/polargrid/config.py +0 -0
  418. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/polargrid/models.py +0 -0
  419. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/qwen/__init__.py +0 -0
  420. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/qwen/ai.py +0 -0
  421. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/qwen/config.py +0 -0
  422. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/qwen/models.py +0 -0
  423. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/rcs/__init__.py +0 -0
  424. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/rcs/base.py +0 -0
  425. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/rcs/mock.py +0 -0
  426. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/sendgrid/__init__.py +0 -0
  427. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/sendgrid/config.py +0 -0
  428. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/sendgrid/email.py +0 -0
  429. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/sinch/__init__.py +0 -0
  430. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/sinch/config.py +0 -0
  431. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/sinch/sms.py +0 -0
  432. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/sms/__init__.py +0 -0
  433. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/sms/base.py +0 -0
  434. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/sms/meta.py +0 -0
  435. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/sms/mock.py +0 -0
  436. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/sms/phone.py +0 -0
  437. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/teams/__init__.py +0 -0
  438. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/teams/base.py +0 -0
  439. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/teams/bot_framework.py +0 -0
  440. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/teams/config.py +0 -0
  441. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/teams/conversation_store.py +0 -0
  442. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/teams/mock.py +0 -0
  443. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/teams/models.py +0 -0
  444. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/teams/webhook.py +0 -0
  445. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telegram/__init__.py +0 -0
  446. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telegram/api.py +0 -0
  447. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telegram/base.py +0 -0
  448. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telegram/bot.py +0 -0
  449. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telegram/config.py +0 -0
  450. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telegram/entities.py +0 -0
  451. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telegram/mock.py +0 -0
  452. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telegram/update.py +0 -0
  453. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telegram/webhook.py +0 -0
  454. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telnyx/__init__.py +0 -0
  455. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telnyx/_signature.py +0 -0
  456. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telnyx/config.py +0 -0
  457. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telnyx/rcs.py +0 -0
  458. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telnyx/sms.py +0 -0
  459. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/twilio/__init__.py +0 -0
  460. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/twilio/_signature.py +0 -0
  461. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/twilio/config.py +0 -0
  462. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/twilio/rcs.py +0 -0
  463. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/twilio/sms.py +0 -0
  464. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/twilio/webhook.py +0 -0
  465. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/url_safety.py +0 -0
  466. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/utils.py +0 -0
  467. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/vllm/__init__.py +0 -0
  468. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/vllm/config.py +0 -0
  469. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/voicemeup/__init__.py +0 -0
  470. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/voicemeup/config.py +0 -0
  471. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/voicemeup/sms.py +0 -0
  472. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/whatsapp/__init__.py +0 -0
  473. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/whatsapp/base.py +0 -0
  474. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/whatsapp/mock.py +0 -0
  475. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/whatsapp/personal.py +0 -0
  476. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/xai/__init__.py +0 -0
  477. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/xai/ai.py +0 -0
  478. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/xai/config.py +0 -0
  479. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/xai/image.py +0 -0
  480. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/xai/image_models.py +0 -0
  481. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/xai/models.py +0 -0
  482. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/xai/realtime.py +0 -0
  483. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/xai/realtime_models.py +0 -0
  484. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/xai/voices.py +0 -0
  485. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/py.typed +0 -0
  486. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/realtime/__init__.py +0 -0
  487. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/realtime/_subscription.py +0 -0
  488. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/realtime/base.py +0 -0
  489. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/realtime/memory.py +0 -0
  490. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/realtime/redis.py +0 -0
  491. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/recorder/__init__.py +0 -0
  492. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/recorder/_pyav_mux.py +0 -0
  493. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/recorder/_room_recorder_manager.py +0 -0
  494. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/recorder/base.py +0 -0
  495. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/recorder/mock.py +0 -0
  496. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/recorder/pyav.py +0 -0
  497. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/sandbox/__init__.py +0 -0
  498. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/sandbox/executor.py +0 -0
  499. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/sandbox/models.py +0 -0
  500. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/sandbox/tools.py +0 -0
  501. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/scoring/__init__.py +0 -0
  502. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/scoring/base.py +0 -0
  503. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/scoring/hook.py +0 -0
  504. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/scoring/mock.py +0 -0
  505. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/scoring/tracker.py +0 -0
  506. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/skills/__init__.py +0 -0
  507. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/skills/errors.py +0 -0
  508. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/skills/executor.py +0 -0
  509. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/skills/models.py +0 -0
  510. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/skills/parser.py +0 -0
  511. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/skills/paths.py +0 -0
  512. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/skills/registry.py +0 -0
  513. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/sources/__init__.py +0 -0
  514. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/sources/base.py +0 -0
  515. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/sources/buzz.py +0 -0
  516. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/sources/discord.py +0 -0
  517. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/sources/neonize.py +0 -0
  518. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/sources/sse.py +0 -0
  519. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/sources/websocket.py +0 -0
  520. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/store/__init__.py +0 -0
  521. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/store/base.py +0 -0
  522. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/store/memory.py +0 -0
  523. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/store/postgres.py +0 -0
  524. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/store/postgres_lock.py +0 -0
  525. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/store/postgres_mappers.py +0 -0
  526. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/store/postgres_schema.py +0 -0
  527. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/store/sqlite.py +0 -0
  528. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tasks/__init__.py +0 -0
  529. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tasks/base.py +0 -0
  530. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tasks/cache.py +0 -0
  531. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tasks/delegate.py +0 -0
  532. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tasks/memory.py +0 -0
  533. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tasks/models.py +0 -0
  534. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/telemetry/__init__.py +0 -0
  535. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/telemetry/base.py +0 -0
  536. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/telemetry/config.py +0 -0
  537. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/telemetry/console.py +0 -0
  538. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/telemetry/context.py +0 -0
  539. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/telemetry/mock.py +0 -0
  540. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/telemetry/noop.py +0 -0
  541. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/telemetry/opentelemetry.py +0 -0
  542. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/telemetry/pyroscope.py +0 -0
  543. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/telemetry/redaction.py +0 -0
  544. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tools/__init__.py +0 -0
  545. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tools/base.py +0 -0
  546. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tools/compose.py +0 -0
  547. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tools/context.py +0 -0
  548. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tools/external.py +0 -0
  549. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tools/human_input.py +0 -0
  550. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tools/mcp.py +0 -0
  551. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tools/policy.py +0 -0
  552. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tools/validation.py +0 -0
  553. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/__init__.py +0 -0
  554. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/ai_integration.py +0 -0
  555. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/avatar/__init__.py +0 -0
  556. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/avatar/base.py +0 -0
  557. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/avatar/mock.py +0 -0
  558. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/avatar/musetalk.py +0 -0
  559. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/avatar/websocket.py +0 -0
  560. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/backends/__init__.py +0 -0
  561. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/backends/base.py +0 -0
  562. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/backends/fastrtc.py +0 -0
  563. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/backends/local.py +0 -0
  564. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/backends/mock.py +0 -0
  565. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/backends/rtp.py +0 -0
  566. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/backends/screen.py +0 -0
  567. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/backends/sip.py +0 -0
  568. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/backends/websocket.py +0 -0
  569. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/base.py +0 -0
  570. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/bridge.py +0 -0
  571. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/events.py +0 -0
  572. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/__init__.py +0 -0
  573. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/config.py +0 -0
  574. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/decoder/__init__.py +0 -0
  575. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/decoder/base.py +0 -0
  576. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/decoder/mock.py +0 -0
  577. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/decoder/pyav.py +0 -0
  578. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/encoder/__init__.py +0 -0
  579. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/encoder/base.py +0 -0
  580. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/encoder/pyav.py +0 -0
  581. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/engine.py +0 -0
  582. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/filter/__init__.py +0 -0
  583. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/filter/base.py +0 -0
  584. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/filter/censor.py +0 -0
  585. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/filter/mediapipe_face_touch.py +0 -0
  586. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/filter/mock.py +0 -0
  587. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/filter/mock_face_touch.py +0 -0
  588. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/filter/watermark.py +0 -0
  589. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/filter/yolo.py +0 -0
  590. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/overlay/__init__.py +0 -0
  591. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/overlay/base.py +0 -0
  592. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/overlay/filter.py +0 -0
  593. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/overlay/image.py +0 -0
  594. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/overlay/mock.py +0 -0
  595. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/overlay/rich.py +0 -0
  596. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/overlay/subtitle.py +0 -0
  597. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/overlay/text.py +0 -0
  598. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/resizer/__init__.py +0 -0
  599. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/resizer/base.py +0 -0
  600. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/resizer/mock.py +0 -0
  601. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/resizer/pyav.py +0 -0
  602. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/transform/__init__.py +0 -0
  603. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/transform/base.py +0 -0
  604. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/transform/effects.py +0 -0
  605. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/transform/mock.py +0 -0
  606. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/recorder/__init__.py +0 -0
  607. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/recorder/base.py +0 -0
  608. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/recorder/mock.py +0 -0
  609. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/recorder/opencv.py +0 -0
  610. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/recorder/pyav.py +0 -0
  611. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/utils.py +0 -0
  612. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/video_frame.py +0 -0
  613. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/vision/__init__.py +0 -0
  614. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/vision/base.py +0 -0
  615. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/vision/encode.py +0 -0
  616. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/vision/gemini.py +0 -0
  617. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/vision/mock.py +0 -0
  618. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/vision/openai.py +0 -0
  619. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/vision/screen_input.py +0 -0
  620. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/vision/screen_tool.py +0 -0
  621. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/vision/webcam_tool.py +0 -0
  622. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/__init__.py +0 -0
  623. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/_g711.py +0 -0
  624. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/_limits.py +0 -0
  625. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/_sounddevice.py +0 -0
  626. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/audio_frame.py +0 -0
  627. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/auth.py +0 -0
  628. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/__init__.py +0 -0
  629. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/_mulaw.py +0 -0
  630. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/_resample.py +0 -0
  631. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/_sip_types.py +0 -0
  632. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/_webrtc_auth.py +0 -0
  633. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/buzz_huddle.py +0 -0
  634. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/fastrtc.py +0 -0
  635. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/local.py +0 -0
  636. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/mock.py +0 -0
  637. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/rtp.py +0 -0
  638. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/sip.py +0 -0
  639. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/sip_auth.py +0 -0
  640. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/twilio_ws.py +0 -0
  641. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/webtransport.py +0 -0
  642. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/base.py +0 -0
  643. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/bridge.py +0 -0
  644. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/capture/__init__.py +0 -0
  645. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/capture/base.py +0 -0
  646. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/capture/local.py +0 -0
  647. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/capture/mock.py +0 -0
  648. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/events.py +0 -0
  649. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/inbound.py +0 -0
  650. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/interruption.py +0 -0
  651. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/__init__.py +0 -0
  652. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/_telemetry.py +0 -0
  653. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/aec/__init__.py +0 -0
  654. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/aec/base.py +0 -0
  655. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/aec/mock.py +0 -0
  656. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/aec/speex.py +0 -0
  657. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/aec/webrtc.py +0 -0
  658. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/agc/__init__.py +0 -0
  659. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/agc/base.py +0 -0
  660. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/agc/mock.py +0 -0
  661. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/agc/simple.py +0 -0
  662. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/backchannel/__init__.py +0 -0
  663. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/backchannel/base.py +0 -0
  664. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/backchannel/mock.py +0 -0
  665. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/config.py +0 -0
  666. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/debug_taps.py +0 -0
  667. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/denoiser/__init__.py +0 -0
  668. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/denoiser/aicoustics.py +0 -0
  669. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/denoiser/base.py +0 -0
  670. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/denoiser/mock.py +0 -0
  671. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/denoiser/rnnoise.py +0 -0
  672. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/denoiser/sherpa_onnx.py +0 -0
  673. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/denoiser/webrtc.py +0 -0
  674. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/diarization/__init__.py +0 -0
  675. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/diarization/base.py +0 -0
  676. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/diarization/mock.py +0 -0
  677. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/diarization/sherpa_onnx.py +0 -0
  678. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/dtmf/__init__.py +0 -0
  679. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/dtmf/base.py +0 -0
  680. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/dtmf/mock.py +0 -0
  681. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/engine.py +0 -0
  682. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/mixer/__init__.py +0 -0
  683. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/mixer/base.py +0 -0
  684. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/mixer/numpy.py +0 -0
  685. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/mixer/python.py +0 -0
  686. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/offload.py +0 -0
  687. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/postprocessor/__init__.py +0 -0
  688. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/postprocessor/base.py +0 -0
  689. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/recorder/__init__.py +0 -0
  690. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/recorder/_wav_writer.py +0 -0
  691. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/recorder/base.py +0 -0
  692. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/recorder/mock.py +0 -0
  693. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/recorder/wav.py +0 -0
  694. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/resampler/__init__.py +0 -0
  695. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/resampler/base.py +0 -0
  696. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/resampler/linear.py +0 -0
  697. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/resampler/mock.py +0 -0
  698. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/resampler/numpy.py +0 -0
  699. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/resampler/sinc.py +0 -0
  700. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/turn/__init__.py +0 -0
  701. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/turn/base.py +0 -0
  702. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/turn/mock.py +0 -0
  703. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/turn/smart_turn.py +0 -0
  704. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/vad/__init__.py +0 -0
  705. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/vad/base.py +0 -0
  706. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/vad/energy.py +0 -0
  707. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/vad/mock.py +0 -0
  708. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/vad/sherpa_onnx.py +0 -0
  709. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/realtime/__init__.py +0 -0
  710. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/realtime/_fastrtc_playback.py +0 -0
  711. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/realtime/bridge.py +0 -0
  712. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/realtime/events.py +0 -0
  713. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/realtime/fastrtc_transport.py +0 -0
  714. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/realtime/injection.py +0 -0
  715. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/realtime/mock.py +0 -0
  716. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/realtime/provider.py +0 -0
  717. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/realtime/reasoning.py +0 -0
  718. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/realtime/ws_transport.py +0 -0
  719. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/stt/__init__.py +0 -0
  720. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/stt/base.py +0 -0
  721. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/stt/deepgram.py +0 -0
  722. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/stt/gemini.py +0 -0
  723. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/stt/gemini_audio.py +0 -0
  724. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/stt/gemini_transcript.py +0 -0
  725. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/stt/gradium.py +0 -0
  726. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/stt/language.py +0 -0
  727. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/stt/mock.py +0 -0
  728. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/stt/qwen3.py +0 -0
  729. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/stt/sherpa_onnx.py +0 -0
  730. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/testing/__init__.py +0 -0
  731. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/testing/backend.py +0 -0
  732. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/testing/trace.py +0 -0
  733. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/testing/wav.py +0 -0
  734. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/tts/__init__.py +0 -0
  735. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/tts/audio_utils.py +0 -0
  736. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/tts/base.py +0 -0
  737. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/tts/elevenlabs.py +0 -0
  738. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/tts/filters.py +0 -0
  739. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/tts/gemini.py +0 -0
  740. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/tts/gradium.py +0 -0
  741. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/tts/grok.py +0 -0
  742. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/tts/mock.py +0 -0
  743. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/tts/neutts.py +0 -0
  744. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/tts/qwen3.py +0 -0
  745. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/tts/sentence_splitter.py +0 -0
  746. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/tts/sherpa_onnx.py +0 -0
  747. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/webrtc/LICENSE +0 -0
  748. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/webrtc/__init__.py +0 -0
  749. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/webrtc/stream.py +0 -0
  750. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/webrtc/tracks.py +0 -0
  751. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/webrtc/utils.py +0 -0
  752. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/webrtc/webrtc_connection_mixin.py +0 -0
  753. {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/webrtc/websocket.py +0 -0
  754. {roomkit-0.76.0 → roomkit-0.78.0}/tests/__init__.py +0 -0
  755. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/__init__.py +0 -0
  756. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/lane_audio.py +0 -0
  757. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_backend_abc.py +0 -0
  758. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_activity.py +0 -0
  759. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_attach_failure.py +0 -0
  760. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_channel.py +0 -0
  761. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_gating.py +0 -0
  762. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_hot_plug.py +0 -0
  763. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_identity.py +0 -0
  764. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_lane.py +0 -0
  765. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_metadata.py +0 -0
  766. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_mixer.py +0 -0
  767. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_outbound.py +0 -0
  768. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_pure_transport.py +0 -0
  769. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_races.py +0 -0
  770. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_realtime.py +0 -0
  771. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_realtime_hot_plug.py +0 -0
  772. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_realtime_voice.py +0 -0
  773. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_recording.py +0 -0
  774. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_recording_isolation.py +0 -0
  775. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_teardown_failure.py +0 -0
  776. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_livekit_backend.py +0 -0
  777. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_livekit_live.py +0 -0
  778. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_livekit_mapping.py +0 -0
  779. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_mock_backend.py +0 -0
  780. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_mock_injection.py +0 -0
  781. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_models.py +0 -0
  782. {roomkit-0.76.0 → roomkit-0.78.0}/tests/conftest.py +0 -0
  783. {roomkit-0.76.0 → roomkit-0.78.0}/tests/delivery/__init__.py +0 -0
  784. {roomkit-0.76.0 → roomkit-0.78.0}/tests/delivery/test_base.py +0 -0
  785. {roomkit-0.76.0 → roomkit-0.78.0}/tests/delivery/test_integration.py +0 -0
  786. {roomkit-0.76.0 → roomkit-0.78.0}/tests/delivery/test_memory.py +0 -0
  787. {roomkit-0.76.0 → roomkit-0.78.0}/tests/delivery/test_redis.py +0 -0
  788. {roomkit-0.76.0 → roomkit-0.78.0}/tests/delivery/test_redis_integration.py +0 -0
  789. {roomkit-0.76.0 → roomkit-0.78.0}/tests/delivery/test_serialization.py +0 -0
  790. {roomkit-0.76.0 → roomkit-0.78.0}/tests/delivery/test_targeted.py +0 -0
  791. {roomkit-0.76.0 → roomkit-0.78.0}/tests/delivery/test_worker.py +0 -0
  792. {roomkit-0.76.0 → roomkit-0.78.0}/tests/http_timeout_fakes.py +0 -0
  793. {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/__init__.py +0 -0
  794. {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_framework_orchestration.py +0 -0
  795. {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_handoff.py +0 -0
  796. {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_loop_strategy.py +0 -0
  797. {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_orchestration_base.py +0 -0
  798. {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_pipeline.py +0 -0
  799. {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_router.py +0 -0
  800. {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_session_audit.py +0 -0
  801. {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_state.py +0 -0
  802. {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_status_bus.py +0 -0
  803. {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_status_redis.py +0 -0
  804. {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_strategy_behavioral.py +0 -0
  805. {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_strategy_loop.py +0 -0
  806. {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_strategy_pipeline.py +0 -0
  807. {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_strategy_supervisor.py +0 -0
  808. {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_strategy_swarm.py +0 -0
  809. {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_supervisor_inline.py +0 -0
  810. {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_supervisor_strategy.py +0 -0
  811. {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_tool_audit.py +0 -0
  812. {roomkit-0.76.0 → roomkit-0.78.0}/tests/providers/__init__.py +0 -0
  813. {roomkit-0.76.0 → roomkit-0.78.0}/tests/providers/gemini/__init__.py +0 -0
  814. {roomkit-0.76.0 → roomkit-0.78.0}/tests/providers/gemini/test_reconfigure_preservation.py +0 -0
  815. {roomkit-0.76.0 → roomkit-0.78.0}/tests/providers/gemini/test_schema.py +0 -0
  816. {roomkit-0.76.0 → roomkit-0.78.0}/tests/providers/openai/__init__.py +0 -0
  817. {roomkit-0.76.0 → roomkit-0.78.0}/tests/providers/openai/test_reconfigure.py +0 -0
  818. {roomkit-0.76.0 → roomkit-0.78.0}/tests/redis_fakes.py +0 -0
  819. {roomkit-0.76.0 → roomkit-0.78.0}/tests/stress/__init__.py +0 -0
  820. {roomkit-0.76.0 → roomkit-0.78.0}/tests/stress/test_stress_core.py +0 -0
  821. {roomkit-0.76.0 → roomkit-0.78.0}/tests/stress/test_stress_messaging.py +0 -0
  822. {roomkit-0.76.0 → roomkit-0.78.0}/tests/stress/test_stress_voice.py +0 -0
  823. {roomkit-0.76.0 → roomkit-0.78.0}/tests/tasks/__init__.py +0 -0
  824. {roomkit-0.76.0 → roomkit-0.78.0}/tests/tasks/test_cache.py +0 -0
  825. {roomkit-0.76.0 → roomkit-0.78.0}/tests/tasks/test_child_room_trace.py +0 -0
  826. {roomkit-0.76.0 → roomkit-0.78.0}/tests/tasks/test_delegate.py +0 -0
  827. {roomkit-0.76.0 → roomkit-0.78.0}/tests/tasks/test_integration.py +0 -0
  828. {roomkit-0.76.0 → roomkit-0.78.0}/tests/tasks/test_models.py +0 -0
  829. {roomkit-0.76.0 → roomkit-0.78.0}/tests/tasks/test_runner.py +0 -0
  830. {roomkit-0.76.0 → roomkit-0.78.0}/tests/tasks/test_structured_result.py +0 -0
  831. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_addressing.py +0 -0
  832. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_aec_bench.py +0 -0
  833. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_aec_pipeline.py +0 -0
  834. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_ai_docs.py +0 -0
  835. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_ai_response_plain_stream.py +0 -0
  836. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_ai_response_transcript.py +0 -0
  837. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_ai_stream_contract.py +0 -0
  838. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_ai_streaming_thinking.py +0 -0
  839. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_ai_streaming_tool_events.py +0 -0
  840. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_ai_streaming_tool_loop.py +0 -0
  841. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_aicoustics_denoiser.py +0 -0
  842. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_anam_realtime.py +0 -0
  843. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_audio_backpressure.py +0 -0
  844. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_audio_capture_source.py +0 -0
  845. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_audio_limits.py +0 -0
  846. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_audio_pipeline.py +0 -0
  847. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_auto_connect.py +0 -0
  848. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_av_channel.py +0 -0
  849. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_avatar.py +0 -0
  850. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_before_ai_generation.py +0 -0
  851. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_before_deliver_gate.py +0 -0
  852. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_binding_permission_inheritance.py +0 -0
  853. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_bridge_hook_modification.py +0 -0
  854. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_buzz_huddle_backend.py +0 -0
  855. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channel_abc.py +0 -0
  856. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channel_attach_contract.py +0 -0
  857. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/__init__.py +0 -0
  858. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_acp.py +0 -0
  859. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_acp_empty_prompt.py +0 -0
  860. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_acp_usage.py +0 -0
  861. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_acp_usage_boundaries.py +0 -0
  862. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_agent.py +0 -0
  863. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_ai.py +0 -0
  864. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_ai_active_turns.py +0 -0
  865. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_ai_empty_retry.py +0 -0
  866. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_ai_loop_rules.py +0 -0
  867. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_ai_response_loop_end_reason.py +0 -0
  868. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_ai_retry.py +0 -0
  869. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_ai_skill_gating.py +0 -0
  870. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_ai_steering.py +0 -0
  871. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_ai_streaming_compaction.py +0 -0
  872. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_ai_tool_loop.py +0 -0
  873. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_compact_context_tool_pairs.py +0 -0
  874. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_email.py +0 -0
  875. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_http.py +0 -0
  876. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_loop_end_marker.py +0 -0
  877. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_loop_end_reason_nonstreaming.py +0 -0
  878. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_messenger.py +0 -0
  879. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_multimodal_tool_result.py +0 -0
  880. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_sms.py +0 -0
  881. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_telegram.py +0 -0
  882. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_tool_usage_memory.py +0 -0
  883. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_turn_config.py +0 -0
  884. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_websocket.py +0 -0
  885. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_whatsapp.py +0 -0
  886. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_chat_benchmark.py +0 -0
  887. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_chat_quality.py +0 -0
  888. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_check_models.py +0 -0
  889. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_circuit_breaker.py +0 -0
  890. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_cli_activity.py +0 -0
  891. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_cli_channel.py +0 -0
  892. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_cli_console.py +0 -0
  893. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_cli_prompt_shell.py +0 -0
  894. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_cli_select.py +0 -0
  895. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_commit_atomicity.py +0 -0
  896. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_compacting_cache.py +0 -0
  897. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_compose_tool_handlers.py +0 -0
  898. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_config_secret_hygiene.py +0 -0
  899. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_configs.py +0 -0
  900. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_conformance_level0.py +0 -0
  901. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_console.py +0 -0
  902. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_context_carry_forward.py +0 -0
  903. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_context_visibility.py +0 -0
  904. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_current_turn_budget.py +0 -0
  905. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_dangling_recovery.py +0 -0
  906. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_delivery_cancellation.py +0 -0
  907. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_delivery_cancellation_streams.py +0 -0
  908. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_delivery_order.py +0 -0
  909. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_delivery_outcomes.py +0 -0
  910. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_delivery_strategies.py +0 -0
  911. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_denoiser_rnnoise_loader.py +0 -0
  912. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_describe_screen_tool.py +0 -0
  913. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_describe_webcam_tool.py +0 -0
  914. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_drain_barge_in.py +0 -0
  915. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_edit_delete_authorization.py +0 -0
  916. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_energy_vad.py +0 -0
  917. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_enums.py +0 -0
  918. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_event_ops.py +0 -0
  919. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_event_text.py +0 -0
  920. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_examples_audio.py +0 -0
  921. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_external_tool_handler.py +0 -0
  922. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_face_touch_filter.py +0 -0
  923. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_fastrtc_audio_session.py +0 -0
  924. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_fastrtc_playback.py +0 -0
  925. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_fastrtc_realtime_transport.py +0 -0
  926. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_framework.py +0 -0
  927. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_framework_aware.py +0 -0
  928. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_framework_events.py +0 -0
  929. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_framework_queries.py +0 -0
  930. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_framework_status_bus.py +0 -0
  931. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_gemini_context_preservation.py +0 -0
  932. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_gemini_realtime_failfast.py +0 -0
  933. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_gemini_transcript_dedup.py +0 -0
  934. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_hook_payload_modification.py +0 -0
  935. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_hook_side_effects.py +0 -0
  936. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_hooks.py +0 -0
  937. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_http_timeouts.py +0 -0
  938. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_human_input.py +0 -0
  939. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_idempotent_redelivery.py +0 -0
  940. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_identity_hooks.py +0 -0
  941. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_identity_pipeline.py +0 -0
  942. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_identity_unknown_outcomes.py +0 -0
  943. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_inbound_connection_budget.py +0 -0
  944. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_inbound_deferred.py +0 -0
  945. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_inbound_error_surfacing.py +0 -0
  946. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_inbound_rate_limit.py +0 -0
  947. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_inbound_response_events.py +0 -0
  948. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_inbound_routing.py +0 -0
  949. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_inbound_routing_ambiguity.py +0 -0
  950. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_inbound_stream_cancellation.py +0 -0
  951. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_inbound_stream_error_propagation.py +0 -0
  952. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_inbound_visibility.py +0 -0
  953. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_integration/__init__.py +0 -0
  954. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_integration/test_ai_assistant.py +0 -0
  955. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_integration/test_ai_chain_depth.py +0 -0
  956. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_integration/test_cerebras_live.py +0 -0
  957. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_integration/test_cross_channel.py +0 -0
  958. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_integration/test_dynamic_channels.py +0 -0
  959. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_integration/test_human_ai.py +0 -0
  960. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_integration/test_identity_resolution.py +0 -0
  961. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_integration/test_observer.py +0 -0
  962. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_integration/test_regenerate.py +0 -0
  963. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_integration/test_sin_scanning.py +0 -0
  964. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_interruption.py +0 -0
  965. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_interruption_partials.py +0 -0
  966. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_interruption_pipeline.py +0 -0
  967. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_invalid_tool_repeat_guard.py +0 -0
  968. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_knowledge_postgres.py +0 -0
  969. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_lanes.py +0 -0
  970. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_lanes_multiworker.py +0 -0
  971. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_lifecycle_hooks.py +0 -0
  972. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_local_backend_aec.py +0 -0
  973. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_locks.py +0 -0
  974. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_log_redaction.py +0 -0
  975. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_mcp_structured_content.py +0 -0
  976. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_mcp_tool_provider.py +0 -0
  977. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_mcp_tools.py +0 -0
  978. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_media_recorder.py +0 -0
  979. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_memory.py +0 -0
  980. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_memory_new.py +0 -0
  981. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_memory_wrappers.py +0 -0
  982. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_mock_providers.py +0 -0
  983. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_models.py +0 -0
  984. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_observability.py +0 -0
  985. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_openai_live.py +0 -0
  986. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_opencv_recorder.py +0 -0
  987. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_opentelemetry.py +0 -0
  988. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_optional_imports.py +0 -0
  989. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_outbound_audio_pacer.py +0 -0
  990. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_parallel_tool_cleanup.py +0 -0
  991. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_participant_membership.py +0 -0
  992. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_personaplex_realtime.py +0 -0
  993. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_pipeline_debug_taps.py +0 -0
  994. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_pipeline_engine.py +0 -0
  995. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_pipeline_providers.py +0 -0
  996. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_pipeline_resampler.py +0 -0
  997. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_pipeline_resampler_numpy.py +0 -0
  998. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_pipeline_resampler_sinc.py +0 -0
  999. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_postgres_lock.py +0 -0
  1000. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_postgres_multiprocess.py +0 -0
  1001. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_postgres_store.py +0 -0
  1002. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_precommit_timeout.py +0 -0
  1003. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_proactive_delivery.py +0 -0
  1004. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_proactive_delivery_voice.py +0 -0
  1005. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_protocol_trace.py +0 -0
  1006. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/__init__.py +0 -0
  1007. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/conftest.py +0 -0
  1008. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_ai_models.py +0 -0
  1009. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_anam_avatar.py +0 -0
  1010. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_anam_realtime.py +0 -0
  1011. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_anthropic.py +0 -0
  1012. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_azure.py +0 -0
  1013. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_azure_image.py +0 -0
  1014. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_buzz.py +0 -0
  1015. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_cerebras.py +0 -0
  1016. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_cerebras_tool_arrays.py +0 -0
  1017. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_deepseek.py +0 -0
  1018. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_discord.py +0 -0
  1019. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_elasticemail.py +0 -0
  1020. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_gemini.py +0 -0
  1021. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_gemini_image.py +0 -0
  1022. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_gemini_list_models.py +0 -0
  1023. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_gemini_realtime.py +0 -0
  1024. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_gemini_vertex.py +0 -0
  1025. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_http.py +0 -0
  1026. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_http_timeouts.py +0 -0
  1027. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_image.py +0 -0
  1028. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_image_advanced.py +0 -0
  1029. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_image_parts.py +0 -0
  1030. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_image_sdk_contracts.py +0 -0
  1031. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_image_stream.py +0 -0
  1032. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_litellm.py +0 -0
  1033. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_messenger.py +0 -0
  1034. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_mistral.py +0 -0
  1035. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_ollama.py +0 -0
  1036. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_openai.py +0 -0
  1037. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_openai_image.py +0 -0
  1038. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_openai_realtime.py +0 -0
  1039. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_openrouter.py +0 -0
  1040. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_openrouter_image.py +0 -0
  1041. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_personaplex_realtime.py +0 -0
  1042. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_phone.py +0 -0
  1043. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_polargrid.py +0 -0
  1044. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_qwen.py +0 -0
  1045. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_rcs.py +0 -0
  1046. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_realtime_models.py +0 -0
  1047. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_realtime_voices.py +0 -0
  1048. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_sendgrid.py +0 -0
  1049. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_sinch.py +0 -0
  1050. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_sms_utils.py +0 -0
  1051. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_teams.py +0 -0
  1052. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_teams_webhook.py +0 -0
  1053. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_telegram_api.py +0 -0
  1054. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_telegram_bot.py +0 -0
  1055. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_telegram_entities.py +0 -0
  1056. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_telegram_update.py +0 -0
  1057. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_telegram_webhook.py +0 -0
  1058. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_telnyx.py +0 -0
  1059. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_telnyx_rcs.py +0 -0
  1060. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_twilio.py +0 -0
  1061. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_vllm.py +0 -0
  1062. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_voicemeup.py +0 -0
  1063. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_whatsapp_personal.py +0 -0
  1064. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_xai.py +0 -0
  1065. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_xai_image.py +0 -0
  1066. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_xai_realtime.py +0 -0
  1067. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_public_api.py +0 -0
  1068. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_pyav_decode_native.py +0 -0
  1069. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_pyav_media_recorder.py +0 -0
  1070. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_pyav_recorder.py +0 -0
  1071. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_rate_limiter.py +0 -0
  1072. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_raw_payload_preservation.py +0 -0
  1073. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime.py +0 -0
  1074. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_av_channel.py +0 -0
  1075. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_elevenlabs.py +0 -0
  1076. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_fixed_tools.py +0 -0
  1077. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_full_duplex.py +0 -0
  1078. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_g711.py +0 -0
  1079. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_hook_coverage.py +0 -0
  1080. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_reconfiguration.py +0 -0
  1081. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_reconnection.py +0 -0
  1082. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_redis.py +0 -0
  1083. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_resample_offload.py +0 -0
  1084. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_skill_delivery.py +0 -0
  1085. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_skills.py +0 -0
  1086. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_tool_recovery.py +0 -0
  1087. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_tool_search.py +0 -0
  1088. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_voice.py +0 -0
  1089. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_voice_integration.py +0 -0
  1090. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_xai.py +0 -0
  1091. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_recent_events_window.py +0 -0
  1092. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_recording_consent.py +0 -0
  1093. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_recording_wiring.py +0 -0
  1094. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_reentry_block_side_effects.py +0 -0
  1095. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_related_family_tools.py +0 -0
  1096. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_release_script.py +0 -0
  1097. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_repeated_result_note.py +0 -0
  1098. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_resilience.py +0 -0
  1099. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_response_metadata.py +0 -0
  1100. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_response_visibility.py +0 -0
  1101. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_retrieval_memory.py +0 -0
  1102. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_retry_retryability.py +0 -0
  1103. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_rfc_arbitrations.py +0 -0
  1104. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_rfc_conformance.py +0 -0
  1105. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_rfc_framework_events.py +0 -0
  1106. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_rfc_write_gates.py +0 -0
  1107. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_rnnoise.py +0 -0
  1108. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_room_org_scoping.py +0 -0
  1109. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_room_status_enforcement.py +0 -0
  1110. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_router.py +0 -0
  1111. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_rtp_video_backend.py +0 -0
  1112. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_scoring.py +0 -0
  1113. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_screen_capture_backend.py +0 -0
  1114. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_screen_input.py +0 -0
  1115. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_session_started.py +0 -0
  1116. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_sherpa_onnx_denoiser.py +0 -0
  1117. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_sherpa_onnx_vad.py +0 -0
  1118. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_sip_audio_clock.py +0 -0
  1119. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_sip_auth.py +0 -0
  1120. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_sip_dial.py +0 -0
  1121. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_sip_helpers.py +0 -0
  1122. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_sip_realtime_transport.py +0 -0
  1123. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_sip_video_backend.py +0 -0
  1124. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_skill_activation.py +0 -0
  1125. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_skill_tool_gating.py +0 -0
  1126. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_skills.py +0 -0
  1127. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_skills_integration.py +0 -0
  1128. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_smart_turn.py +0 -0
  1129. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_smoke_quickstart.py +0 -0
  1130. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_source_rate_limit.py +0 -0
  1131. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_source_url_redaction.py +0 -0
  1132. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_sources.py +0 -0
  1133. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_sources_init.py +0 -0
  1134. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_sources_neonize.py +0 -0
  1135. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_sources_sse.py +0 -0
  1136. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_sources_websocket.py +0 -0
  1137. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_speaker_attribution.py +0 -0
  1138. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_speex_aec.py +0 -0
  1139. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_store_activity.py +0 -0
  1140. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_store_binding_contract.py +0 -0
  1141. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_store_identity_scoping.py +0 -0
  1142. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_store_lifecycle_immutability.py +0 -0
  1143. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_store_memory.py +0 -0
  1144. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_store_postgres.py +0 -0
  1145. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_store_sqlite.py +0 -0
  1146. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_streaming_before_broadcast.py +0 -0
  1147. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_stt_deepgram_teardown.py +0 -0
  1148. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_stt_gemini.py +0 -0
  1149. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_stt_qwen3.py +0 -0
  1150. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_summarizing_memory.py +0 -0
  1151. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_supervisor.py +0 -0
  1152. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_task_planner.py +0 -0
  1153. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_task_utils.py +0 -0
  1154. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_telemetry.py +0 -0
  1155. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_telemetry_pyroscope.py +0 -0
  1156. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_threading.py +0 -0
  1157. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tool_arg_fold.py +0 -0
  1158. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tool_arg_validation.py +0 -0
  1159. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tool_context.py +0 -0
  1160. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tool_eviction_room_scope.py +0 -0
  1161. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tool_policy.py +0 -0
  1162. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tool_protocol.py +0 -0
  1163. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tool_repeat_guard.py +0 -0
  1164. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tool_round_cap.py +0 -0
  1165. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tool_search_text.py +0 -0
  1166. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_transport_auth.py +0 -0
  1167. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tts_elevenlabs.py +0 -0
  1168. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tts_gemini.py +0 -0
  1169. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tts_grok.py +0 -0
  1170. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tts_neutts.py +0 -0
  1171. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tts_qwen3.py +0 -0
  1172. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tts_text_split.py +0 -0
  1173. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_turn_detection.py +0 -0
  1174. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_twilio_ws_backend.py +0 -0
  1175. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_unified_tool_call.py +0 -0
  1176. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_vad_debug_logging.py +0 -0
  1177. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_video.py +0 -0
  1178. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_video_ai_integration.py +0 -0
  1179. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_video_channel.py +0 -0
  1180. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_video_local.py +0 -0
  1181. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_video_pipeline.py +0 -0
  1182. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_video_pipeline_config.py +0 -0
  1183. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_video_recording.py +0 -0
  1184. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_video_session_isolation.py +0 -0
  1185. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_video_transform.py +0 -0
  1186. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_vision_gemini.py +0 -0
  1187. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_vision_openai.py +0 -0
  1188. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice.py +0 -0
  1189. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_batch_stt.py +0 -0
  1190. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_binding_gate.py +0 -0
  1191. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_channel_aec.py +0 -0
  1192. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_delivery_idempotency.py +0 -0
  1193. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_delivery_recovery.py +0 -0
  1194. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_delivery_store.py +0 -0
  1195. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_dsp_vectorized.py +0 -0
  1196. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_fastrtc.py +0 -0
  1197. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_frame_limit.py +0 -0
  1198. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_inbound.py +0 -0
  1199. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_injection_results.py +0 -0
  1200. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_integration.py +0 -0
  1201. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_local.py +0 -0
  1202. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_map.py +0 -0
  1203. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_rtp.py +0 -0
  1204. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_say_play.py +0 -0
  1205. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_security.py +0 -0
  1206. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_session_lifecycle.py +0 -0
  1207. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_sherpa_onnx.py +0 -0
  1208. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_streaming_ai_tts.py +0 -0
  1209. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_streaming_stt.py +0 -0
  1210. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_stt_language.py +0 -0
  1211. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_webtransport.py +0 -0
  1212. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_wake_word_backlog.py +0 -0
  1213. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_wav_recorder.py +0 -0
  1214. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_webrtc_offer_auth.py +0 -0
  1215. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_webrtc_rtc_configuration.py +0 -0
  1216. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_websocket_lifecycle.py +0 -0
  1217. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_websocket_room_scoping.py +0 -0
  1218. {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_yolo_filter.py +0 -0
  1219. {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/__init__.py +0 -0
  1220. {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_av_channel_fastrtc.py +0 -0
  1221. {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_fastrtc_video_backend.py +0 -0
  1222. {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_overlay_filter.py +0 -0
  1223. {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_overlay_image.py +0 -0
  1224. {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_overlay_rich.py +0 -0
  1225. {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_overlay_subtitle.py +0 -0
  1226. {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_overlay_text.py +0 -0
  1227. {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_screen_input.py +0 -0
  1228. {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_screen_input_tools.py +0 -0
  1229. {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_video_bridge.py +0 -0
  1230. {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_video_effects.py +0 -0
  1231. {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_watermark_filter.py +0 -0
  1232. {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_websocket_avatar.py +0 -0
  1233. {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_websocket_video_backend.py +0 -0
  1234. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/__init__.py +0 -0
  1235. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/backends/__init__.py +0 -0
  1236. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/backends/test_rtp.py +0 -0
  1237. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/backends/test_sip.py +0 -0
  1238. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/backends/test_sip_coverage.py +0 -0
  1239. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/backends/test_webtransport.py +0 -0
  1240. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/__init__.py +0 -0
  1241. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/stream_conformance.py +0 -0
  1242. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/test_aicoustics_denoiser.py +0 -0
  1243. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/test_offload_callbacks.py +0 -0
  1244. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/test_per_stream_regression.py +0 -0
  1245. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/test_rnnoise_denoiser.py +0 -0
  1246. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/test_sherpa_diarization.py +0 -0
  1247. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/test_simple_agc.py +0 -0
  1248. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/test_smart_turn.py +0 -0
  1249. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/test_speex_aec.py +0 -0
  1250. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/test_stream_conformance.py +0 -0
  1251. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/test_stream_entry_point.py +0 -0
  1252. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/test_webrtc_aec.py +0 -0
  1253. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/test_webrtc_denoiser.py +0 -0
  1254. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/realtime/__init__.py +0 -0
  1255. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/realtime/test_fastrtc_transport.py +0 -0
  1256. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/realtime/test_realtime_bridge.py +0 -0
  1257. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/realtime/test_ws_transport.py +0 -0
  1258. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/stt/__init__.py +0 -0
  1259. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/stt/test_deepgram.py +0 -0
  1260. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/stt/test_deepgram_stream_language.py +0 -0
  1261. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/stt/test_gradium_stt.py +0 -0
  1262. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/stt/test_language_lock.py +0 -0
  1263. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/stt/test_qwen3_asr.py +0 -0
  1264. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/test_bridge.py +0 -0
  1265. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/test_inbound_offload.py +0 -0
  1266. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/test_testing_backend.py +0 -0
  1267. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/test_testing_trace.py +0 -0
  1268. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/test_testing_wav.py +0 -0
  1269. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/test_tts_filters.py +0 -0
  1270. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/test_voice_close_providers.py +0 -0
  1271. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/test_voice_tts_filter.py +0 -0
  1272. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/tts/__init__.py +0 -0
  1273. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/tts/test_elevenlabs.py +0 -0
  1274. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/tts/test_gradium_tts.py +0 -0
  1275. {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/tts/test_qwen3_tts.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: roomkit
3
- Version: 0.76.0
3
+ Version: 0.78.0
4
4
  Summary: Pure async Python library for multi-channel conversations
5
5
  Project-URL: Homepage, https://roomkit.live
6
6
  Project-URL: Documentation, https://www.roomkit.live/docs/
@@ -0,0 +1 @@
1
+ __version__ = "0.78.0"
@@ -12,7 +12,7 @@ from typing import TYPE_CHECKING, Any, Protocol, runtime_checkable
12
12
  from roomkit.models.enums import Access, HookTrigger
13
13
  from roomkit.voice.audio_frame import AudioFrame
14
14
  from roomkit.voice.base import VoiceSessionState
15
- from roomkit.voice.utils import rms_db
15
+ from roomkit.voice.utils import pcm16_has_activity, rms_db
16
16
 
17
17
  if TYPE_CHECKING:
18
18
  from roomkit.core.framework import RoomKit
@@ -167,6 +167,7 @@ class RealtimeAudioMixin:
167
167
  _playback_position_ms: dict[str, float]
168
168
  _playback_buffer: dict[str, tuple[float, float]]
169
169
 
170
+ _note_provider_output: Any
170
171
  _track_task: Any # see RealtimeAudioHost — cross-mixin
171
172
  _pipeline_submit_inbound: Any # see VoicePipelineMixin — cross-mixin
172
173
  _flush_and_signal_end: Any # see RealtimeResponseMixin — cross-mixin
@@ -788,6 +789,8 @@ class RealtimeAudioMixin:
788
789
  Each item captures the current generation counter so that chunks
789
790
  enqueued before an interrupt are silently discarded.
790
791
  """
792
+ if self._provider.full_duplex and pcm16_has_activity(audio):
793
+ self._note_provider_output(session.id)
791
794
  with self._state_lock:
792
795
  if session.id not in self._sessions:
793
796
  return
@@ -82,6 +82,8 @@ class RealtimeDelegationHost(Protocol):
82
82
 
83
83
  def _update_idle_event(self, session_id: str) -> None: ...
84
84
 
85
+ def _expect_provider_output(self, session_id: str) -> None: ...
86
+
85
87
 
86
88
  class RealtimeDelegationMixin:
87
89
  """Reasoning-delegation handling for :class:`RealtimeVoiceChannel`.
@@ -104,6 +106,7 @@ class RealtimeDelegationMixin:
104
106
 
105
107
  _track_task: Any # see RealtimeDelegationHost — cross-mixin
106
108
  _rt_span_ctx: Any # see RealtimeDelegationHost — cross-mixin
109
+ _expect_provider_output: Any
107
110
  _update_idle_event: Any # see RealtimeDelegationHost — cross-mixin
108
111
  _telemetry_provider: Any # see RealtimeDelegationHost — cross-mixin
109
112
  _authorize_realtime_tool: Any # see RealtimeToolsMixin
@@ -275,6 +278,8 @@ class RealtimeDelegationMixin:
275
278
  if not text:
276
279
  continue
277
280
  answered = True
281
+ if output.spoken:
282
+ self._expect_provider_output(session.id)
278
283
  await self._provider.submit_delegation_output(
279
284
  session, delegation_id, text, spoken=output.spoken
280
285
  )
@@ -308,6 +313,7 @@ class RealtimeDelegationMixin:
308
313
  if session.state == VoiceSessionState.ENDED:
309
314
  return
310
315
  try:
316
+ self._expect_provider_output(session.id)
311
317
  await self._provider.submit_delegation_output(
312
318
  session, delegation_id, text, spoken=True
313
319
  )
@@ -103,6 +103,8 @@ class RealtimeToolsHost(Protocol):
103
103
 
104
104
  def _update_idle_event(self, session_id: str) -> None: ...
105
105
 
106
+ def _expect_provider_output(self, session_id: str) -> None: ...
107
+
106
108
 
107
109
  class RealtimeToolsMixin:
108
110
  """Tool call execution for RealtimeVoiceChannel.
@@ -134,6 +136,7 @@ class RealtimeToolsMixin:
134
136
  _telemetry_provider: Any
135
137
 
136
138
  _track_task: Any # see RealtimeToolsHost — cross-mixin
139
+ _expect_provider_output: Any
137
140
  _update_idle_event: Any
138
141
  _compose_session_prompt: Any
139
142
  _compose_session_tools: Any
@@ -503,12 +506,7 @@ class RealtimeToolsMixin:
503
506
  """Confirm delivery only while the session remains live."""
504
507
  if session.state == VoiceSessionState.ENDED:
505
508
  return False
506
- self._awaiting_tool_response.add(session.id)
507
- # A provider may end the function-call response while its handler
508
- # runs. Submission starts the wait for the next provider response;
509
- # that earlier boundary cannot make the acknowledgement idle.
510
- self._provider_idle[session.id] = False
511
- self._update_idle_event(session.id)
509
+ self._expect_provider_output(session.id)
512
510
  await self._provider.submit_tool_result(session, call_id, result)
513
511
  return session.state != VoiceSessionState.ENDED
514
512
 
@@ -10,6 +10,7 @@ from typing import TYPE_CHECKING, Any, Protocol, runtime_checkable
10
10
  from roomkit.core.exceptions import ChannelNotFoundError
11
11
  from roomkit.models.enums import HookTrigger
12
12
  from roomkit.models.event import TextContent
13
+ from roomkit.voice.realtime.provider import RealtimeVoiceProvider
13
14
 
14
15
  if TYPE_CHECKING:
15
16
  from roomkit.core.framework import RoomKit
@@ -38,6 +39,7 @@ class RealtimeTranscriptionHost(Protocol):
38
39
  _rt_span_ctx: Get the telemetry span context for a session.
39
40
  """
40
41
 
42
+ _provider: RealtimeVoiceProvider
41
43
  _state_lock: threading.Lock
42
44
  _session_rooms: dict[str, str]
43
45
  _barge_in_active: set[str]
@@ -62,6 +64,7 @@ class RealtimeTranscriptionMixin:
62
64
  Host contract: :class:`RealtimeTranscriptionHost`.
63
65
  """
64
66
 
67
+ _provider: RealtimeVoiceProvider
65
68
  _state_lock: threading.Lock
66
69
  _session_rooms: dict[str, str]
67
70
  _barge_in_active: set[str]
@@ -73,6 +76,7 @@ class RealtimeTranscriptionMixin:
73
76
  channel_id: str
74
77
  provider_name: str | None
75
78
 
79
+ _note_provider_output: Any
76
80
  _track_task: Any # see RealtimeTranscriptionHost — cross-mixin
77
81
  _send_client_message: Any # see RealtimeTranscriptionHost — cross-mixin
78
82
  _rt_span_ctx: Any # see RealtimeTranscriptionHost — cross-mixin
@@ -81,6 +85,8 @@ class RealtimeTranscriptionMixin:
81
85
  self, session: VoiceSession, text: str, role: str, is_final: bool
82
86
  ) -> Any:
83
87
  """Handle transcription from provider."""
88
+ if self._provider.full_duplex and role == "assistant" and text and not is_final:
89
+ self._note_provider_output(session.id)
84
90
  try:
85
91
  loop = asyncio.get_running_loop()
86
92
  except RuntimeError:
@@ -5,16 +5,18 @@ from __future__ import annotations
5
5
  import asyncio
6
6
  import contextlib
7
7
  import contextvars
8
+ import inspect
8
9
  import logging
9
10
  import threading
11
+ import time
10
12
  from collections.abc import Awaitable, Callable
11
13
  from concurrent.futures import ThreadPoolExecutor
12
14
  from copy import deepcopy
13
- from dataclasses import dataclass
15
+ from dataclasses import dataclass, field
14
16
  from typing import TYPE_CHECKING, Any
15
17
  from uuid import uuid4
16
18
 
17
- from roomkit.channels._realtime_audio import RealtimeAudioMixin
19
+ from roomkit.channels._realtime_audio import _MAX_QUEUED_AUDIO_CHUNKS, RealtimeAudioMixin
18
20
  from roomkit.channels._realtime_context import (
19
21
  _current_voice_session as _current_voice_session,
20
22
  )
@@ -80,6 +82,15 @@ class _ConnectingSession:
80
82
 
81
83
  task: asyncio.Task[VoiceSession]
82
84
  disconnected: bool = False
85
+ deferred: bool = False
86
+ callbacks: list[tuple[Callable[..., Any], tuple[Any, ...]]] = field(default_factory=list)
87
+ audio_bytes: int = 0
88
+ failure: Exception | None = None
89
+
90
+ def fail(self, error: Exception) -> None:
91
+ self.failure = error
92
+ if not self.task.done() and not self.task.cancelling():
93
+ self.task.cancel()
83
94
 
84
95
 
85
96
  class RealtimeVoiceChannel(
@@ -511,16 +522,16 @@ class RealtimeVoiceChannel(
511
522
  self._turn_spans: dict[str, str] = {}
512
523
 
513
524
  # Wire internal callbacks
514
- provider.on_audio(self._on_provider_audio)
515
- provider.on_transcription(self._on_provider_transcription)
516
- provider.on_transcription(self._on_transcript_fragment)
517
- provider.on_speech_start(self._on_provider_speech_start)
518
- provider.on_speech_end(self._on_provider_speech_end)
519
- provider.on_tool_call(self._on_provider_tool_call)
520
- provider.on_delegation(self._on_provider_delegation)
521
- provider.on_response_start(self._on_provider_response_start)
522
- provider.on_response_end(self._on_provider_response_end)
523
- provider.on_error(self._on_provider_error)
525
+ provider.on_audio(self._gate_provider_callback(self._on_provider_audio))
526
+ provider.on_transcription(self._gate_provider_callback(self._on_provider_transcription))
527
+ provider.on_transcription(self._gate_provider_callback(self._on_transcript_fragment))
528
+ provider.on_speech_start(self._gate_provider_callback(self._on_provider_speech_start))
529
+ provider.on_speech_end(self._gate_provider_callback(self._on_provider_speech_end))
530
+ provider.on_tool_call(self._gate_provider_callback(self._on_provider_tool_call))
531
+ provider.on_delegation(self._gate_provider_callback(self._on_provider_delegation))
532
+ provider.on_response_start(self._gate_provider_callback(self._on_provider_response_start))
533
+ provider.on_response_end(self._gate_provider_callback(self._on_provider_response_end))
534
+ provider.on_error(self._on_startup_provider_error)
524
535
 
525
536
  # Direct audio path: only when no pipeline is configured.
526
537
  # When pipeline= is set, _create_pipeline() registers
@@ -614,6 +625,12 @@ class RealtimeVoiceChannel(
614
625
  else:
615
626
  idle.clear()
616
627
 
628
+ def _expect_provider_output(self, session_id: str) -> None:
629
+ """Keep idle closed until a submitted result has an assistant continuation."""
630
+ self._awaiting_tool_response.add(session_id)
631
+ self._provider_idle[session_id] = False
632
+ self._update_idle_event(session_id)
633
+
617
634
  def _note_provider_output(self, session_id: str) -> None:
618
635
  """A new provider response can continue submitted tool results."""
619
636
  if session_id in self._awaiting_tool_response:
@@ -995,7 +1012,16 @@ class RealtimeVoiceChannel(
995
1012
  Args:
996
1013
  room_id: The room to join.
997
1014
  participant_id: The participant's ID.
998
- connection: Protocol-specific connection (e.g. WebSocket).
1015
+ connection: Protocol-specific connection (e.g. WebSocket), or an
1016
+ awaitable resolving to it. With an awaitable, provider setup
1017
+ starts while the connection is pending (e.g. SIP ringing).
1018
+ Cancel the start task if the connection will never arrive.
1019
+ Both branches belong to this session and are rolled back on
1020
+ failure. The channel publishes the session only when both are ready.
1021
+ Provider callbacks wait for publication in a bounded startup
1022
+ queue; exceeding 2 MiB of audio or 500 events aborts startup.
1023
+ Monotonic timestamps are written to metadata's
1024
+ ``connection_timing`` for measuring setup and pre-answer cost.
999
1025
  metadata: Optional session metadata. May include overrides
1000
1026
  for system_prompt, voice, tools, temperature.
1001
1027
 
@@ -1015,7 +1041,7 @@ class RealtimeVoiceChannel(
1015
1041
  task = asyncio.create_task(
1016
1042
  self._start_session(session, connection), name=f"rt_connect:{session.id}"
1017
1043
  )
1018
- pending = _ConnectingSession(task)
1044
+ pending = _ConnectingSession(task, deferred=inspect.isawaitable(connection))
1019
1045
  self._connecting_sessions[session.id] = pending
1020
1046
  try:
1021
1047
  return await task
@@ -1030,6 +1056,9 @@ class RealtimeVoiceChannel(
1030
1056
  await _finish_cleanup(self.end_session(session))
1031
1057
  else:
1032
1058
  await _finish_cleanup(self._cleanup_failed_start(session))
1059
+ pending = self._connecting_sessions.get(session.id)
1060
+ if pending is not None and pending.failure is not None:
1061
+ raise pending.failure from None
1033
1062
  raise
1034
1063
 
1035
1064
  async def _cleanup_failed_start(self, session: VoiceSession) -> None:
@@ -1081,6 +1110,8 @@ class RealtimeVoiceChannel(
1081
1110
  room_id, participant_id = session.room_id, session.participant_id
1082
1111
  self._session_config_locks[session.id] = asyncio.Lock()
1083
1112
  meta = session.metadata
1113
+ timing: dict[str, float] = {}
1114
+ meta["connection_timing"] = timing
1084
1115
  # Start telemetry session span early so transport/provider connect
1085
1116
  # phases appear as children in Jaeger.
1086
1117
  telemetry = self._telemetry_provider
@@ -1173,56 +1204,89 @@ class RealtimeVoiceChannel(
1173
1204
  if self._pipeline is not None:
1174
1205
  self._pipeline_session_active(session)
1175
1206
 
1176
- with telemetry.span(
1177
- SpanKind.BACKEND_CONNECT,
1178
- "transport.accept",
1179
- parent_id=session_span_id,
1180
- session_id=session.id,
1181
- attributes={Attr.BACKEND_TYPE: self._transport.name},
1182
- ):
1183
- await self._transport.accept(session, connection)
1184
- self._check_connecting_session(session)
1185
-
1186
- # Connect to provider (with telemetry span).
1187
- # If provider.connect fails, clean up the already-accepted transport
1188
- # session to avoid leaking the connection.
1189
- try:
1190
- self._prepare_session_audio(session)
1207
+ async def accept_transport() -> None:
1208
+ resolved = await connection if inspect.isawaitable(connection) else connection
1209
+ self._check_connecting_session(session)
1191
1210
  with telemetry.span(
1192
1211
  SpanKind.BACKEND_CONNECT,
1193
- "provider.connect",
1212
+ "transport.accept",
1194
1213
  parent_id=session_span_id,
1195
1214
  session_id=session.id,
1196
- attributes={Attr.BACKEND_TYPE: self._provider.name},
1215
+ attributes={Attr.BACKEND_TYPE: self._transport.name},
1197
1216
  ):
1198
- await self._provider.connect(
1199
- session,
1200
- system_prompt=system_prompt,
1201
- voice=voice,
1202
- tools=tools,
1203
- temperature=temperature,
1204
- input_sample_rate=self._input_sample_rate,
1205
- output_sample_rate=self._output_sample_rate,
1206
- server_vad=self._provider.full_duplex or not has_pipeline_vad,
1207
- provider_config=provider_config,
1208
- )
1209
- except (Exception, asyncio.CancelledError) as exc:
1210
- # CancelledError here is the orchestrator deliberately aborting
1211
- # a still-handshaking session (e.g. carrier hung up before the
1212
- # provider WS connected). It's expected control flow, not a
1213
- # bug — log it as info without a traceback so dashboards stay
1214
- # quiet. Real failures keep their full stack trace.
1215
- if isinstance(exc, asyncio.CancelledError):
1217
+ await self._transport.accept(session, resolved)
1218
+ self._check_connecting_session(session)
1219
+ self._prepare_session_audio(session)
1220
+ timing["transport_ready_at"] = time.monotonic()
1221
+
1222
+ async def connect_provider() -> None:
1223
+ # Connect to provider (with telemetry span).
1224
+ # If provider.connect fails, clean up the already-accepted transport
1225
+ # session to avoid leaking the connection.
1226
+ try:
1227
+ timing["provider_connect_started_at"] = time.monotonic()
1228
+ with telemetry.span(
1229
+ SpanKind.BACKEND_CONNECT,
1230
+ "provider.connect",
1231
+ parent_id=session_span_id,
1232
+ session_id=session.id,
1233
+ attributes={Attr.BACKEND_TYPE: self._provider.name},
1234
+ ):
1235
+ await self._provider.connect(
1236
+ session,
1237
+ system_prompt=system_prompt,
1238
+ voice=voice,
1239
+ tools=tools,
1240
+ temperature=temperature,
1241
+ input_sample_rate=self._input_sample_rate,
1242
+ output_sample_rate=self._output_sample_rate,
1243
+ server_vad=self._provider.full_duplex or not has_pipeline_vad,
1244
+ provider_config=provider_config,
1245
+ )
1246
+ timing["provider_ready_at"] = time.monotonic()
1216
1247
  logger.info(
1217
- "provider.connect cancelled for session %s — transport cleaned up",
1218
- session.id,
1219
- )
1220
- else:
1221
- logger.exception(
1222
- "provider.connect failed for session %s; cleaned up transport",
1248
+ "Realtime provider ready: room=%s session=%s connect_ms=%.1f",
1249
+ room_id,
1223
1250
  session.id,
1251
+ (timing["provider_ready_at"] - timing["provider_connect_started_at"]) * 1000,
1224
1252
  )
1225
- raise
1253
+ except (Exception, asyncio.CancelledError) as exc:
1254
+ # CancelledError here is the orchestrator deliberately aborting
1255
+ # a still-handshaking session (e.g. carrier hung up before the
1256
+ # provider WS connected). It's expected control flow, not a
1257
+ # bug — log it as info without a traceback so dashboards stay
1258
+ # quiet. Real failures keep their full stack trace.
1259
+ if isinstance(exc, asyncio.CancelledError):
1260
+ logger.info(
1261
+ "provider.connect cancelled for session %s — transport cleaned up",
1262
+ session.id,
1263
+ )
1264
+ else:
1265
+ logger.exception(
1266
+ "provider.connect failed for session %s; cleaned up transport",
1267
+ session.id,
1268
+ )
1269
+ raise
1270
+
1271
+ if inspect.isawaitable(connection):
1272
+ # One handshake owns both branches. gather alone would leave its
1273
+ # sibling running after an error; drain both before rollback.
1274
+ branches = [
1275
+ asyncio.create_task(accept_transport(), name=f"rt_transport:{session.id}"),
1276
+ asyncio.create_task(connect_provider(), name=f"rt_provider:{session.id}"),
1277
+ ]
1278
+ try:
1279
+ await asyncio.gather(*branches)
1280
+ finally:
1281
+ for branch in branches:
1282
+ if not branch.done():
1283
+ branch.cancel()
1284
+ await asyncio.gather(*branches, return_exceptions=True)
1285
+ else:
1286
+ # Preserve ordinary startup ordering, including codec validation
1287
+ # before any provider connection is opened.
1288
+ await accept_transport()
1289
+ await connect_provider()
1226
1290
 
1227
1291
  self._check_connecting_session(session)
1228
1292
  session.state = VoiceSessionState.ACTIVE
@@ -1231,6 +1295,12 @@ class RealtimeVoiceChannel(
1231
1295
  self._session_rooms[session.id] = room_id
1232
1296
 
1233
1297
  await self._finish_session_start(session, room_id, participant_id)
1298
+ self._check_connecting_session(session)
1299
+ pending = self._connecting_sessions[session.id]
1300
+ pending.deferred = False
1301
+ for callback, args in pending.callbacks:
1302
+ callback(*args)
1303
+ pending.callbacks.clear()
1234
1304
 
1235
1305
  return session
1236
1306
 
@@ -1754,6 +1824,41 @@ class RealtimeVoiceChannel(
1754
1824
 
1755
1825
  # -- Internal callbacks --
1756
1826
 
1827
+ def _gate_provider_callback(self, callback: Callable[..., Any]) -> Callable[..., Any]:
1828
+ """Keep startup events ordered until transport and authorization are ready.
1829
+
1830
+ No application task runs while SIP is ringing. Audio enters the normal
1831
+ send FIFO only after the negotiated codec and binding are available.
1832
+ Rollback discards the journal with its connecting-session owner.
1833
+ """
1834
+
1835
+ def dispatch(session: VoiceSession, *args: Any) -> Any:
1836
+ pending = self._connecting_sessions.get(session.id)
1837
+ if pending is None or not pending.deferred:
1838
+ return callback(session, *args)
1839
+ if pending.failure is not None or pending.task.cancelling():
1840
+ return None
1841
+ size = sum(len(arg) for arg in args if isinstance(arg, bytes))
1842
+ if (
1843
+ len(pending.callbacks) >= _MAX_QUEUED_AUDIO_CHUNKS
1844
+ or pending.audio_bytes + size > 2 * 1024 * 1024
1845
+ ):
1846
+ pending.fail(RuntimeError("Provider startup event buffer exceeded"))
1847
+ return None
1848
+ pending.audio_bytes += size
1849
+ pending.callbacks.append((callback, (session, *args)))
1850
+ return None
1851
+
1852
+ return dispatch
1853
+
1854
+ def _on_startup_provider_error(self, session: VoiceSession, code: str, message: str) -> Any:
1855
+ pending = self._connecting_sessions.get(session.id)
1856
+ if pending is not None and session.state == VoiceSessionState.ENDED:
1857
+ pending.fail(RuntimeError(f"Provider connection failed [{code}]: {message}"))
1858
+ self._announce_provider_error(session, code, message)
1859
+ return None
1860
+ return self._on_provider_error(session, code, message)
1861
+
1757
1862
  def _on_client_disconnected(self, session: VoiceSession) -> Any:
1758
1863
  """Handle client disconnection — end the session."""
1759
1864
  try:
@@ -122,7 +122,11 @@ class VoiceOpsMixin(HelpersMixin):
122
122
  so the bridge sends audio through the correct transport.
123
123
  connection: Protocol-specific connection for realtime voice
124
124
  channels (e.g. WebSocket). Required when joining a
125
- :class:`RealtimeVoiceChannel`.
125
+ :class:`RealtimeVoiceChannel`. May be an awaitable resolving
126
+ to that connection: provider setup then overlaps the wait,
127
+ under the same cancellable join. Bound that wait at the call
128
+ site (e.g. the dial timeout); no active session or started hook
129
+ is exposed until both transport and provider are ready.
126
130
 
127
131
  Returns:
128
132
  The voice or video session (created or passed in).
@@ -73,8 +73,8 @@ class OpenAILiveProvider(
73
73
  gates the model's audio on user speech, :meth:`interrupt` and
74
74
  :meth:`truncate_audio` do nothing, and a pipeline VAD stays in the
75
75
  observation role. The wire carries no response or speech boundaries;
76
- this provider synthesizes them from the transcript deltas with a quiet
77
- gap of ``turn_gap_ms`` per speaker (RFC §12.4.1).
76
+ this provider synthesizes them from transcript deltas and assistant audio
77
+ activity, with a quiet gap of ``turn_gap_ms`` per speaker (RFC §12.4.1).
78
78
 
79
79
  **Transcripts.** Partial transcriptions carry *deltas* for both roles and
80
80
  the final carries the whole turn, closed by the gap. A channel that keeps
@@ -3,7 +3,7 @@
3
3
  Translates Live API server events into RoomKit provider callbacks: the
4
4
  dispatch table keyed on the wire event type, one handler per event, and the
5
5
  turn synthesis a full-duplex wire calls for (RFC §12.4.1) — response and
6
- speech boundaries closed by a quiet gap on each speaker's transcript. The
6
+ speech boundaries closed by a quiet gap in transcript or assistant audio activity. The
7
7
  hosted-delegation envelope (``response.event``) is handled by
8
8
  :class:`~roomkit.providers.openai.live_hosted.OpenAILiveHostedDelegationMixin`.
9
9
  """
@@ -32,6 +32,7 @@ from roomkit.providers.openai.live_events import (
32
32
  from roomkit.telemetry.base import Attr
33
33
  from roomkit.voice.base import VoiceSession
34
34
  from roomkit.voice.realtime.provider import RealtimeVoiceProvider
35
+ from roomkit.voice.utils import pcm16_has_activity
35
36
 
36
37
  logger = logging.getLogger("roomkit.providers.openai.live")
37
38
 
@@ -114,6 +115,10 @@ class OpenAILiveEventHandlersMixin(RealtimeVoiceProvider):
114
115
  audio = base64.b64decode(audio_b64)
115
116
  if state.codec is not None:
116
117
  audio = state.codec.decode(audio)
118
+ if pcm16_has_activity(audio):
119
+ # Open before forwarding audio, including audio-only responses.
120
+ # Full-duplex silence is still forwarded, but cannot hold a turn open.
121
+ await state.assistant_turn.feed("")
117
122
  await self._fire(self._audio_callbacks, state.session, audio, label="audio")
118
123
 
119
124
  async def _on_output_transcript_delta(
@@ -361,6 +361,19 @@ class VoiceBackend(ABC):
361
361
  def end_of_response(self, session: VoiceSession) -> None: # noqa: B027
362
362
  """Signal end of an AI response for outbound pacing."""
363
363
 
364
+ async def wait_playback(self, session: VoiceSession) -> bool:
365
+ """Wait for queued response audio to play; return False if discarded.
366
+
367
+ Call after the channel is idle (its EOR has reached the transport).
368
+ Queued transports may override this with a response boundary so that
369
+ continuous silence after the response does not keep the wait open.
370
+ """
371
+ import asyncio
372
+
373
+ while self.is_playing(session):
374
+ await asyncio.sleep(0.02)
375
+ return True
376
+
364
377
  def is_playing(self, session: VoiceSession) -> bool:
365
378
  """Check if audio is currently being sent to the session.
366
379
 
@@ -816,6 +816,13 @@ class SIPAudioMixin:
816
816
  state.send_buffer.clear()
817
817
  return was_playing
818
818
 
819
+ async def wait_playback(self, session: VoiceSession) -> bool:
820
+ """Wait through the latest EOR, including its final RTP packet's duration."""
821
+ state = self._session_states.get(session.id)
822
+ if state is None or state.pacer is None:
823
+ return True
824
+ return await state.pacer.wait_for_response_boundary()
825
+
819
826
  def is_playing(self, session: VoiceSession) -> bool:
820
827
  state = self._session_states.get(session.id)
821
828
  return state.is_playing if state is not None else False
@@ -857,6 +857,7 @@ class SIPCallingMixin:
857
857
  )
858
858
 
859
859
  await out_call.wait_answered(timeout=timeout)
860
+ sip_answered_at = time.monotonic()
860
861
  setup.answered = True
861
862
 
862
863
  # Map call_id early so re-INVITEs arriving during RTP setup are
@@ -908,6 +909,7 @@ class SIPCallingMixin:
908
909
  "callee": to_uri,
909
910
  "room_id": effective_room_id,
910
911
  "direction": "outbound",
912
+ "sip_answered_at": sip_answered_at,
911
913
  "input_sample_rate": actual_codec_rate,
912
914
  "output_sample_rate": actual_codec_rate,
913
915
  "codec_sample_rate": actual_codec_rate,