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.
- {roomkit-0.76.0 → roomkit-0.78.0}/PKG-INFO +1 -1
- roomkit-0.78.0/src/roomkit/_version.py +1 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_realtime_audio.py +4 -1
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_realtime_delegation.py +6 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_realtime_tools.py +4 -6
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_realtime_transcription.py +6 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/realtime_voice.py +161 -56
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/voice_ops.py +5 -1
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/live.py +2 -2
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/live_handlers.py +6 -1
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/base.py +13 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/sip_audio.py +7 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/sip_calling.py +2 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/realtime/pacer.py +61 -16
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/realtime/sip_transport.py +6 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/utils.py +15 -0
- roomkit-0.78.0/tests/test_live_turn_playback.py +103 -0
- roomkit-0.78.0/tests/test_pacer_response_boundary.py +82 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_deepgram.py +35 -2
- roomkit-0.78.0/tests/test_realtime_deferred_connection.py +286 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_playback_lifecycle.py +3 -3
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_reasoning.py +6 -1
- roomkit-0.76.0/src/roomkit/_version.py +0 -1
- {roomkit-0.76.0 → roomkit-0.78.0}/.gitignore +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/AGENTS.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/LICENSE +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/README.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/QUALITY.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/README.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/__main__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/fixtures/quote-policy/SKILL.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/fixtures/quote-policy/references/rules.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/fixtures/quote-policy/scripts/total.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/harness.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/measurement.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/quality.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/quality_oracles.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/quality_report.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/report.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/benchmarks/chat/scenarios.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/README.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/acp.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/ai-channels.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/api-reference.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/architecture.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/conference.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/hooks.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/identity-and-realtime.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/image-generation.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/installation.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/ollama-provider.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/orchestration.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/overview.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/quickstart.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/realtime-voice.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/resilience.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/rooms-and-channels.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/storage.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/testing.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/transport-providers.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/video.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/voice-channels.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/c7/voice-pipeline.md +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/diagrams/architecture.svg +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/diagrams/avatar-pipeline.svg +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/diagrams/message-flow.svg +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/diagrams/orchestration.svg +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/diagrams/room-lifecycle.svg +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/diagrams/video-pipeline.svg +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/diagrams/voice-orchestration.svg +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/docs/diagrams/voice-pipeline.svg +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/llms-full.txt +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/llms.txt +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/pyproject.toml +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/ai_docs.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_acp_client.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_acp_context.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_acp_events.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_acp_usage.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_ai_coalescers.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_ai_context.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_ai_events.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_ai_generation.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_ai_loop_rules.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_ai_policy.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_ai_resilience.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_ai_steering.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_ai_stream_external_tools.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_ai_stream_round.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_ai_streaming.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_ai_tools.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_cli_markdown.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_access.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_activity.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_attachment.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_backlog.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_identity.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_lane.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_lanes.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_metadata.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_mixer.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_operations.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_plug.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_realtime.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_recording.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_recording_events.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_recording_writer.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_room_state.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_roster.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_session.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_shutdown.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_subscription.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_conference_voice.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_dangling_recovery.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_realtime_context.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_realtime_response.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_realtime_skills.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_realtime_speech.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_realtime_tool_recovery.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_realtime_tool_search.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_sandbox_handlers.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_skill_activation.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_skill_constants.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_skill_handlers.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_speaker.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_task_planner.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_tool_eviction.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_tool_search.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_tool_search_constants.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_tool_usage.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_turn_config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_video_hooks.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_video_resources.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_voice_hooks.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_voice_pipeline.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_voice_stt.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_voice_tts.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/_voice_turn.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/acp.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/acp_transport.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/agent.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/ai.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/av.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/cli.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/conference.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/realtime_av.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/transport.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/video.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/voice.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/channels/websocket.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/conference/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/conference/_livekit_mapping.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/conference/_livekit_media.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/conference/_livekit_session.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/conference/_livekit_voice.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/conference/_mock_faults.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/conference/_mock_media.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/conference/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/conference/livekit.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/conference/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/conference/models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/console/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/console/_activity.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/console/_brand.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/console/_chat.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/console/_display.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/console/_hooks.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/console/_shell.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/console/_state.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/console/_terminal.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/console/_tool_preview.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/_delivery_targets.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/_participant_channels.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/_voice_delivery.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/callbacks.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/circuit_breaker.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/delivery.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/event_router.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/exceptions.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/framework.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/hooks.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/inbound_router.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/lanes.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/locks.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/_child_execution.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/channel_ops.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/delegation.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/deliver.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/event_ops.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/greeting.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/helpers.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/hooks_api.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/inbound.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/inbound_identity.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/inbound_locked.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/inbound_streaming.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/lane_execution.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/membership.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/realtime_ops.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/recording.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/regenerate.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/room_lifecycle.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/mixins/source_ops.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/rate_limiter.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/retry.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/router.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/task_utils.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/transcoder.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/core/visibility.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/delivery/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/delivery/_redis_scripts.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/delivery/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/delivery/memory.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/delivery/redis.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/delivery/serialization.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/delivery/worker.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/identity/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/identity/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/identity/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/knowledge/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/knowledge/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/knowledge/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/knowledge/postgres.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/memory/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/memory/_wrapper.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/memory/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/memory/budget_aware.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/memory/compacting.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/memory/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/memory/retrieval.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/memory/sliding_window.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/memory/summarizing.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/memory/token_estimator.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/channel.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/context.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/delivery.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/enums.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/event.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/framework_event.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/hook.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/identity.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/participant.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/pending_input.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/plan_event.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/response_metadata.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/room.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/session_event.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/steering.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/store_filter.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/streaming.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/task.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/thinking_event.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/tool_call.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/trace.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/vision_event.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/models/voice_delivery.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/handoff.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/pipeline.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/result.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/router.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/session_audit.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/state.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/status_bus.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/status_redis.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/loop.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/pipeline.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/supervisor/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/supervisor/_common.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/supervisor/_inject_per_worker.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/supervisor/_inject_strategy.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/supervisor/_install_auto.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/supervisor/core.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/supervisor/delegate.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/supervisor/execution.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/supervisor/prompts.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/supervisor/results.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/supervisor/supervised.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/strategies/swarm.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/orchestration/tool_audit.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/ai/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/ai/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/ai/image_parts.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/ai/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/ai/openai_dialect.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/anam/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/anam/_convert.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/anam/avatar.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/anam/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/anam/realtime.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/anthropic/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/anthropic/ai.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/anthropic/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/anthropic/models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/anthropic/request.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/azure/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/azure/ai.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/azure/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/azure/image.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/buzz/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/buzz/agent.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/buzz/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/buzz/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/buzz/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/buzz/relay.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/cerebras/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/cerebras/ai.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/cerebras/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/cerebras/models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/deepgram/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/deepgram/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/deepgram/realtime.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/deepgram/settings.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/deepgram/voices.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/deepseek/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/deepseek/ai.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/deepseek/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/deepseek/models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/discord/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/discord/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/discord/bot.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/discord/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/discord/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/elasticemail/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/elasticemail/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/elasticemail/email.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/elevenlabs/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/elevenlabs/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/elevenlabs/realtime.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/elevenlabs/voices.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/email/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/email/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/email/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/ai.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/errors.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/image.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/image_models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/realtime.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/realtime_models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/request.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/schema.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/sdk.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/vertex.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/gemini/voices.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/http/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/http/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/http/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/http/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/http/provider.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/http/webhook.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/http_errors.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/image/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/image/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/image/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/image/options.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/image/usage.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/litellm/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/litellm/ai.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/litellm/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/messenger/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/messenger/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/messenger/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/messenger/facebook.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/messenger/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/messenger/webhook.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/mistral/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/mistral/ai.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/mistral/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/mistral/models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/ollama/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/ollama/ai.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/ollama/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/ollama/models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/ai.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/image.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/image_models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/image_stream.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/live_client.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/live_config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/live_events.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/live_hosted.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/live_models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/realtime.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/realtime_base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/realtime_events.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/realtime_models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openai/voices.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openrouter/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openrouter/ai.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openrouter/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openrouter/image.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openrouter/image_models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/openrouter/models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/personaplex/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/personaplex/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/personaplex/realtime.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/personaplex/voices.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/polargrid/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/polargrid/ai.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/polargrid/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/polargrid/models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/qwen/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/qwen/ai.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/qwen/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/qwen/models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/rcs/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/rcs/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/rcs/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/sendgrid/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/sendgrid/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/sendgrid/email.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/sinch/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/sinch/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/sinch/sms.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/sms/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/sms/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/sms/meta.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/sms/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/sms/phone.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/teams/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/teams/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/teams/bot_framework.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/teams/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/teams/conversation_store.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/teams/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/teams/models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/teams/webhook.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telegram/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telegram/api.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telegram/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telegram/bot.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telegram/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telegram/entities.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telegram/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telegram/update.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telegram/webhook.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telnyx/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telnyx/_signature.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telnyx/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telnyx/rcs.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/telnyx/sms.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/twilio/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/twilio/_signature.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/twilio/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/twilio/rcs.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/twilio/sms.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/twilio/webhook.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/url_safety.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/utils.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/vllm/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/vllm/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/voicemeup/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/voicemeup/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/voicemeup/sms.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/whatsapp/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/whatsapp/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/whatsapp/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/whatsapp/personal.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/xai/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/xai/ai.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/xai/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/xai/image.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/xai/image_models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/xai/models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/xai/realtime.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/xai/realtime_models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/providers/xai/voices.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/py.typed +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/realtime/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/realtime/_subscription.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/realtime/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/realtime/memory.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/realtime/redis.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/recorder/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/recorder/_pyav_mux.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/recorder/_room_recorder_manager.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/recorder/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/recorder/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/recorder/pyav.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/sandbox/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/sandbox/executor.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/sandbox/models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/sandbox/tools.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/scoring/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/scoring/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/scoring/hook.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/scoring/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/scoring/tracker.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/skills/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/skills/errors.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/skills/executor.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/skills/models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/skills/parser.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/skills/paths.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/skills/registry.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/sources/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/sources/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/sources/buzz.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/sources/discord.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/sources/neonize.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/sources/sse.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/sources/websocket.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/store/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/store/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/store/memory.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/store/postgres.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/store/postgres_lock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/store/postgres_mappers.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/store/postgres_schema.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/store/sqlite.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tasks/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tasks/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tasks/cache.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tasks/delegate.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tasks/memory.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tasks/models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/telemetry/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/telemetry/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/telemetry/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/telemetry/console.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/telemetry/context.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/telemetry/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/telemetry/noop.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/telemetry/opentelemetry.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/telemetry/pyroscope.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/telemetry/redaction.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tools/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tools/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tools/compose.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tools/context.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tools/external.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tools/human_input.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tools/mcp.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tools/policy.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/tools/validation.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/ai_integration.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/avatar/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/avatar/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/avatar/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/avatar/musetalk.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/avatar/websocket.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/backends/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/backends/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/backends/fastrtc.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/backends/local.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/backends/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/backends/rtp.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/backends/screen.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/backends/sip.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/backends/websocket.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/bridge.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/events.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/decoder/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/decoder/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/decoder/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/decoder/pyav.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/encoder/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/encoder/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/encoder/pyav.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/engine.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/filter/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/filter/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/filter/censor.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/filter/mediapipe_face_touch.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/filter/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/filter/mock_face_touch.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/filter/watermark.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/filter/yolo.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/overlay/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/overlay/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/overlay/filter.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/overlay/image.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/overlay/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/overlay/rich.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/overlay/subtitle.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/overlay/text.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/resizer/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/resizer/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/resizer/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/resizer/pyav.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/transform/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/transform/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/transform/effects.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/pipeline/transform/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/recorder/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/recorder/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/recorder/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/recorder/opencv.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/recorder/pyav.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/utils.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/video_frame.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/vision/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/vision/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/vision/encode.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/vision/gemini.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/vision/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/vision/openai.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/vision/screen_input.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/vision/screen_tool.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/video/vision/webcam_tool.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/_g711.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/_limits.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/_sounddevice.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/audio_frame.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/auth.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/_mulaw.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/_resample.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/_sip_types.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/_webrtc_auth.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/buzz_huddle.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/fastrtc.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/local.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/rtp.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/sip.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/sip_auth.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/twilio_ws.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/backends/webtransport.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/bridge.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/capture/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/capture/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/capture/local.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/capture/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/events.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/inbound.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/interruption.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/_telemetry.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/aec/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/aec/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/aec/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/aec/speex.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/aec/webrtc.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/agc/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/agc/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/agc/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/agc/simple.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/backchannel/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/backchannel/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/backchannel/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/debug_taps.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/denoiser/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/denoiser/aicoustics.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/denoiser/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/denoiser/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/denoiser/rnnoise.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/denoiser/sherpa_onnx.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/denoiser/webrtc.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/diarization/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/diarization/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/diarization/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/diarization/sherpa_onnx.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/dtmf/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/dtmf/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/dtmf/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/engine.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/mixer/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/mixer/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/mixer/numpy.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/mixer/python.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/offload.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/postprocessor/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/postprocessor/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/recorder/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/recorder/_wav_writer.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/recorder/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/recorder/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/recorder/wav.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/resampler/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/resampler/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/resampler/linear.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/resampler/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/resampler/numpy.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/resampler/sinc.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/turn/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/turn/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/turn/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/turn/smart_turn.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/vad/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/vad/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/vad/energy.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/vad/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/pipeline/vad/sherpa_onnx.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/realtime/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/realtime/_fastrtc_playback.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/realtime/bridge.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/realtime/events.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/realtime/fastrtc_transport.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/realtime/injection.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/realtime/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/realtime/provider.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/realtime/reasoning.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/realtime/ws_transport.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/stt/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/stt/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/stt/deepgram.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/stt/gemini.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/stt/gemini_audio.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/stt/gemini_transcript.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/stt/gradium.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/stt/language.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/stt/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/stt/qwen3.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/stt/sherpa_onnx.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/testing/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/testing/backend.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/testing/trace.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/testing/wav.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/tts/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/tts/audio_utils.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/tts/base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/tts/elevenlabs.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/tts/filters.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/tts/gemini.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/tts/gradium.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/tts/grok.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/tts/mock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/tts/neutts.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/tts/qwen3.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/tts/sentence_splitter.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/voice/tts/sherpa_onnx.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/webrtc/LICENSE +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/webrtc/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/webrtc/stream.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/webrtc/tracks.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/webrtc/utils.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/webrtc/webrtc_connection_mixin.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/src/roomkit/webrtc/websocket.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/lane_audio.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_backend_abc.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_activity.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_attach_failure.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_channel.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_gating.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_hot_plug.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_identity.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_lane.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_metadata.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_mixer.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_outbound.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_pure_transport.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_races.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_realtime.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_realtime_hot_plug.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_realtime_voice.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_recording.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_recording_isolation.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_conference_teardown_failure.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_livekit_backend.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_livekit_live.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_livekit_mapping.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_mock_backend.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_mock_injection.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conference/test_models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/conftest.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/delivery/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/delivery/test_base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/delivery/test_integration.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/delivery/test_memory.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/delivery/test_redis.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/delivery/test_redis_integration.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/delivery/test_serialization.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/delivery/test_targeted.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/delivery/test_worker.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/http_timeout_fakes.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_framework_orchestration.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_handoff.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_loop_strategy.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_orchestration_base.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_pipeline.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_router.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_session_audit.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_state.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_status_bus.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_status_redis.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_strategy_behavioral.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_strategy_loop.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_strategy_pipeline.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_strategy_supervisor.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_strategy_swarm.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_supervisor_inline.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_supervisor_strategy.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/orchestration/test_tool_audit.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/providers/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/providers/gemini/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/providers/gemini/test_reconfigure_preservation.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/providers/gemini/test_schema.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/providers/openai/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/providers/openai/test_reconfigure.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/redis_fakes.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/stress/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/stress/test_stress_core.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/stress/test_stress_messaging.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/stress/test_stress_voice.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/tasks/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/tasks/test_cache.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/tasks/test_child_room_trace.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/tasks/test_delegate.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/tasks/test_integration.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/tasks/test_models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/tasks/test_runner.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/tasks/test_structured_result.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_addressing.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_aec_bench.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_aec_pipeline.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_ai_docs.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_ai_response_plain_stream.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_ai_response_transcript.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_ai_stream_contract.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_ai_streaming_thinking.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_ai_streaming_tool_events.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_ai_streaming_tool_loop.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_aicoustics_denoiser.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_anam_realtime.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_audio_backpressure.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_audio_capture_source.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_audio_limits.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_audio_pipeline.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_auto_connect.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_av_channel.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_avatar.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_before_ai_generation.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_before_deliver_gate.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_binding_permission_inheritance.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_bridge_hook_modification.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_buzz_huddle_backend.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channel_abc.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channel_attach_contract.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_acp.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_acp_empty_prompt.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_acp_usage.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_acp_usage_boundaries.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_agent.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_ai.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_ai_active_turns.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_ai_empty_retry.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_ai_loop_rules.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_ai_response_loop_end_reason.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_ai_retry.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_ai_skill_gating.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_ai_steering.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_ai_streaming_compaction.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_ai_tool_loop.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_compact_context_tool_pairs.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_email.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_http.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_loop_end_marker.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_loop_end_reason_nonstreaming.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_messenger.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_multimodal_tool_result.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_sms.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_telegram.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_tool_usage_memory.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_turn_config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_websocket.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_channels/test_whatsapp.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_chat_benchmark.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_chat_quality.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_check_models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_circuit_breaker.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_cli_activity.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_cli_channel.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_cli_console.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_cli_prompt_shell.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_cli_select.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_commit_atomicity.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_compacting_cache.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_compose_tool_handlers.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_config_secret_hygiene.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_configs.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_conformance_level0.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_console.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_context_carry_forward.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_context_visibility.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_current_turn_budget.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_dangling_recovery.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_delivery_cancellation.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_delivery_cancellation_streams.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_delivery_order.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_delivery_outcomes.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_delivery_strategies.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_denoiser_rnnoise_loader.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_describe_screen_tool.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_describe_webcam_tool.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_drain_barge_in.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_edit_delete_authorization.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_energy_vad.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_enums.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_event_ops.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_event_text.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_examples_audio.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_external_tool_handler.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_face_touch_filter.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_fastrtc_audio_session.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_fastrtc_playback.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_fastrtc_realtime_transport.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_framework.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_framework_aware.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_framework_events.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_framework_queries.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_framework_status_bus.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_gemini_context_preservation.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_gemini_realtime_failfast.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_gemini_transcript_dedup.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_hook_payload_modification.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_hook_side_effects.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_hooks.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_http_timeouts.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_human_input.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_idempotent_redelivery.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_identity_hooks.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_identity_pipeline.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_identity_unknown_outcomes.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_inbound_connection_budget.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_inbound_deferred.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_inbound_error_surfacing.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_inbound_rate_limit.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_inbound_response_events.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_inbound_routing.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_inbound_routing_ambiguity.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_inbound_stream_cancellation.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_inbound_stream_error_propagation.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_inbound_visibility.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_integration/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_integration/test_ai_assistant.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_integration/test_ai_chain_depth.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_integration/test_cerebras_live.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_integration/test_cross_channel.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_integration/test_dynamic_channels.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_integration/test_human_ai.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_integration/test_identity_resolution.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_integration/test_observer.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_integration/test_regenerate.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_integration/test_sin_scanning.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_interruption.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_interruption_partials.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_interruption_pipeline.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_invalid_tool_repeat_guard.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_knowledge_postgres.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_lanes.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_lanes_multiworker.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_lifecycle_hooks.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_local_backend_aec.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_locks.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_log_redaction.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_mcp_structured_content.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_mcp_tool_provider.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_mcp_tools.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_media_recorder.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_memory.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_memory_new.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_memory_wrappers.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_mock_providers.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_observability.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_openai_live.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_opencv_recorder.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_opentelemetry.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_optional_imports.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_outbound_audio_pacer.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_parallel_tool_cleanup.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_participant_membership.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_personaplex_realtime.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_pipeline_debug_taps.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_pipeline_engine.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_pipeline_providers.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_pipeline_resampler.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_pipeline_resampler_numpy.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_pipeline_resampler_sinc.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_postgres_lock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_postgres_multiprocess.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_postgres_store.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_precommit_timeout.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_proactive_delivery.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_proactive_delivery_voice.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_protocol_trace.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/conftest.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_ai_models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_anam_avatar.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_anam_realtime.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_anthropic.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_azure.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_azure_image.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_buzz.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_cerebras.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_cerebras_tool_arrays.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_deepseek.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_discord.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_elasticemail.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_gemini.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_gemini_image.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_gemini_list_models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_gemini_realtime.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_gemini_vertex.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_http.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_http_timeouts.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_image.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_image_advanced.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_image_parts.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_image_sdk_contracts.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_image_stream.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_litellm.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_messenger.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_mistral.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_ollama.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_openai.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_openai_image.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_openai_realtime.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_openrouter.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_openrouter_image.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_personaplex_realtime.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_phone.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_polargrid.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_qwen.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_rcs.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_realtime_models.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_realtime_voices.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_sendgrid.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_sinch.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_sms_utils.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_teams.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_teams_webhook.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_telegram_api.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_telegram_bot.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_telegram_entities.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_telegram_update.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_telegram_webhook.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_telnyx.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_telnyx_rcs.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_twilio.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_vllm.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_voicemeup.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_whatsapp_personal.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_xai.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_xai_image.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_providers/test_xai_realtime.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_public_api.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_pyav_decode_native.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_pyav_media_recorder.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_pyav_recorder.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_rate_limiter.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_raw_payload_preservation.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_av_channel.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_elevenlabs.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_fixed_tools.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_full_duplex.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_g711.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_hook_coverage.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_reconfiguration.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_reconnection.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_redis.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_resample_offload.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_skill_delivery.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_skills.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_tool_recovery.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_tool_search.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_voice.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_voice_integration.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_realtime_xai.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_recent_events_window.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_recording_consent.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_recording_wiring.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_reentry_block_side_effects.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_related_family_tools.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_release_script.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_repeated_result_note.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_resilience.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_response_metadata.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_response_visibility.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_retrieval_memory.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_retry_retryability.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_rfc_arbitrations.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_rfc_conformance.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_rfc_framework_events.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_rfc_write_gates.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_rnnoise.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_room_org_scoping.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_room_status_enforcement.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_router.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_rtp_video_backend.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_scoring.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_screen_capture_backend.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_screen_input.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_session_started.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_sherpa_onnx_denoiser.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_sherpa_onnx_vad.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_sip_audio_clock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_sip_auth.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_sip_dial.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_sip_helpers.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_sip_realtime_transport.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_sip_video_backend.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_skill_activation.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_skill_tool_gating.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_skills.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_skills_integration.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_smart_turn.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_smoke_quickstart.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_source_rate_limit.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_source_url_redaction.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_sources.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_sources_init.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_sources_neonize.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_sources_sse.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_sources_websocket.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_speaker_attribution.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_speex_aec.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_store_activity.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_store_binding_contract.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_store_identity_scoping.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_store_lifecycle_immutability.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_store_memory.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_store_postgres.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_store_sqlite.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_streaming_before_broadcast.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_stt_deepgram_teardown.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_stt_gemini.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_stt_qwen3.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_summarizing_memory.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_supervisor.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_task_planner.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_task_utils.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_telemetry.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_telemetry_pyroscope.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_threading.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tool_arg_fold.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tool_arg_validation.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tool_context.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tool_eviction_room_scope.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tool_policy.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tool_protocol.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tool_repeat_guard.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tool_round_cap.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tool_search_text.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_transport_auth.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tts_elevenlabs.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tts_gemini.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tts_grok.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tts_neutts.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tts_qwen3.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_tts_text_split.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_turn_detection.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_twilio_ws_backend.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_unified_tool_call.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_vad_debug_logging.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_video.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_video_ai_integration.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_video_channel.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_video_local.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_video_pipeline.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_video_pipeline_config.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_video_recording.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_video_session_isolation.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_video_transform.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_vision_gemini.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_vision_openai.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_batch_stt.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_binding_gate.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_channel_aec.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_delivery_idempotency.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_delivery_recovery.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_delivery_store.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_dsp_vectorized.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_fastrtc.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_frame_limit.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_inbound.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_injection_results.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_integration.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_local.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_map.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_rtp.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_say_play.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_security.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_session_lifecycle.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_sherpa_onnx.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_streaming_ai_tts.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_streaming_stt.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_stt_language.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_voice_webtransport.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_wake_word_backlog.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_wav_recorder.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_webrtc_offer_auth.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_webrtc_rtc_configuration.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_websocket_lifecycle.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_websocket_room_scoping.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/test_yolo_filter.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_av_channel_fastrtc.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_fastrtc_video_backend.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_overlay_filter.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_overlay_image.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_overlay_rich.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_overlay_subtitle.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_overlay_text.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_screen_input.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_screen_input_tools.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_video_bridge.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_video_effects.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_watermark_filter.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_websocket_avatar.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/video/test_websocket_video_backend.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/backends/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/backends/test_rtp.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/backends/test_sip.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/backends/test_sip_coverage.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/backends/test_webtransport.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/stream_conformance.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/test_aicoustics_denoiser.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/test_offload_callbacks.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/test_per_stream_regression.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/test_rnnoise_denoiser.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/test_sherpa_diarization.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/test_simple_agc.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/test_smart_turn.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/test_speex_aec.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/test_stream_conformance.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/test_stream_entry_point.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/test_webrtc_aec.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/pipeline/test_webrtc_denoiser.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/realtime/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/realtime/test_fastrtc_transport.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/realtime/test_realtime_bridge.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/realtime/test_ws_transport.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/stt/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/stt/test_deepgram.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/stt/test_deepgram_stream_language.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/stt/test_gradium_stt.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/stt/test_language_lock.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/stt/test_qwen3_asr.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/test_bridge.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/test_inbound_offload.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/test_testing_backend.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/test_testing_trace.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/test_testing_wav.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/test_tts_filters.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/test_voice_close_providers.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/test_voice_tts_filter.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/tts/__init__.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/tts/test_elevenlabs.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/tts/test_gradium_tts.py +0 -0
- {roomkit-0.76.0 → roomkit-0.78.0}/tests/voice/tts/test_qwen3_tts.py +0 -0
|
@@ -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.
|
|
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.
|
|
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
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
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
|
-
"
|
|
1212
|
+
"transport.accept",
|
|
1194
1213
|
parent_id=session_span_id,
|
|
1195
1214
|
session_id=session.id,
|
|
1196
|
-
attributes={Attr.BACKEND_TYPE: self.
|
|
1215
|
+
attributes={Attr.BACKEND_TYPE: self._transport.name},
|
|
1197
1216
|
):
|
|
1198
|
-
await self.
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
)
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
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
|
|
1218
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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,
|