@pipedog/core 0.0.0 → 0.2.0
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.
- package/LICENSE +25 -0
- package/NOTICE +9 -0
- package/dist/adapters/base_llm_adapter.d.ts +266 -0
- package/dist/adapters/base_llm_adapter.js +489 -0
- package/dist/adapters/index.d.ts +2 -0
- package/dist/adapters/index.js +8 -0
- package/dist/adapters/schemas/direct_function.d.ts +202 -0
- package/dist/adapters/schemas/direct_function.js +302 -0
- package/dist/adapters/schemas/function_schema.d.ts +67 -0
- package/dist/adapters/schemas/function_schema.js +72 -0
- package/dist/adapters/schemas/index.d.ts +2 -0
- package/dist/adapters/schemas/index.js +8 -0
- package/dist/adapters/schemas/tools_schema.d.ts +57 -0
- package/dist/adapters/schemas/tools_schema.js +79 -0
- package/dist/adapters/services/index.d.ts +2 -0
- package/dist/adapters/services/index.js +8 -0
- package/dist/adapters/services/open_ai_adapter.d.ts +147 -0
- package/dist/adapters/services/open_ai_adapter.js +250 -0
- package/dist/audio/dtmf/dtmf_data.d.ts +3 -0
- package/dist/audio/dtmf/dtmf_data.js +22 -0
- package/dist/audio/dtmf/index.d.ts +2 -0
- package/dist/audio/dtmf/index.js +8 -0
- package/dist/audio/dtmf/types.d.ts +31 -0
- package/dist/audio/dtmf/types.js +35 -0
- package/dist/audio/dtmf/utils.d.ts +13 -0
- package/dist/audio/dtmf/utils.js +62 -0
- package/dist/audio/filters/base_audio_filter.d.ts +51 -0
- package/dist/audio/filters/base_audio_filter.js +17 -0
- package/dist/audio/filters/index.d.ts +2 -0
- package/dist/audio/filters/index.js +8 -0
- package/dist/audio/index.d.ts +2 -0
- package/dist/audio/index.js +8 -0
- package/dist/audio/krisp_instance.d.ts +95 -0
- package/dist/audio/krisp_instance.js +229 -0
- package/dist/audio/mixers/base_audio_mixer.d.ts +56 -0
- package/dist/audio/mixers/base_audio_mixer.js +16 -0
- package/dist/audio/mixers/index.d.ts +2 -0
- package/dist/audio/mixers/index.js +8 -0
- package/dist/audio/resamplers/base_audio_resampler.d.ts +46 -0
- package/dist/audio/resamplers/base_audio_resampler.js +35 -0
- package/dist/audio/resamplers/engine.d.ts +60 -0
- package/dist/audio/resamplers/engine.js +89 -0
- package/dist/audio/resamplers/index.d.ts +2 -0
- package/dist/audio/resamplers/index.js +8 -0
- package/dist/audio/resamplers/resampy_resampler.d.ts +10 -0
- package/dist/audio/resamplers/resampy_resampler.js +15 -0
- package/dist/audio/resamplers/sinc_engine.d.ts +10 -0
- package/dist/audio/resamplers/sinc_engine.js +235 -0
- package/dist/audio/resamplers/soxr_resampler.d.ts +58 -0
- package/dist/audio/resamplers/soxr_resampler.js +79 -0
- package/dist/audio/resamplers/soxr_stream_resampler.d.ts +78 -0
- package/dist/audio/resamplers/soxr_stream_resampler.js +159 -0
- package/dist/audio/turn/base_turn_analyzer.d.ts +84 -0
- package/dist/audio/turn/base_turn_analyzer.js +61 -0
- package/dist/audio/turn/index.d.ts +2 -0
- package/dist/audio/turn/index.js +8 -0
- package/dist/audio/turn/smart_turn/_whisper_features.d.ts +30 -0
- package/dist/audio/turn/smart_turn/_whisper_features.js +225 -0
- package/dist/audio/turn/smart_turn/base_smart_turn.d.ts +94 -0
- package/dist/audio/turn/smart_turn/base_smart_turn.js +239 -0
- package/dist/audio/turn/smart_turn/local_smart_turn_v3.d.ts +76 -0
- package/dist/audio/turn/smart_turn/local_smart_turn_v3.js +151 -0
- package/dist/audio/utils.d.ts +224 -0
- package/dist/audio/utils.js +634 -0
- package/dist/audio/vad/data/index.d.ts +2 -0
- package/dist/audio/vad/data/index.js +8 -0
- package/dist/audio/vad/index.d.ts +2 -0
- package/dist/audio/vad/index.js +8 -0
- package/dist/audio/vad/vad_analyzer.d.ts +134 -0
- package/dist/audio/vad/vad_analyzer.js +249 -0
- package/dist/audio/vad/vad_controller.d.ts +143 -0
- package/dist/audio/vad/vad_controller.js +228 -0
- package/dist/audio/volume.d.ts +38 -0
- package/dist/audio/volume.js +75 -0
- package/dist/bus/adapters/base.d.ts +35 -0
- package/dist/bus/adapters/base.js +19 -0
- package/dist/bus/adapters/index.d.ts +10 -0
- package/dist/bus/adapters/index.js +15 -0
- package/dist/bus/adapters/llm_context_adapter.d.ts +36 -0
- package/dist/bus/adapters/llm_context_adapter.js +82 -0
- package/dist/bus/adapters/tools_schema_adapter.d.ts +25 -0
- package/dist/bus/adapters/tools_schema_adapter.js +70 -0
- package/dist/bus/bridge_processor.d.ts +111 -0
- package/dist/bus/bridge_processor.js +166 -0
- package/dist/bus/bus.d.ts +110 -0
- package/dist/bus/bus.js +200 -0
- package/dist/bus/index.d.ts +22 -0
- package/dist/bus/index.js +27 -0
- package/dist/bus/local/async_queue.d.ts +12 -0
- package/dist/bus/local/async_queue.js +21 -0
- package/dist/bus/local/index.d.ts +3 -0
- package/dist/bus/local/index.js +8 -0
- package/dist/bus/messages.d.ts +378 -0
- package/dist/bus/messages.js +357 -0
- package/dist/bus/network/index.d.ts +16 -0
- package/dist/bus/network/index.js +21 -0
- package/dist/bus/queue.d.ts +27 -0
- package/dist/bus/queue.js +51 -0
- package/dist/bus/serializers/base.d.ts +25 -0
- package/dist/bus/serializers/base.js +14 -0
- package/dist/bus/serializers/index.d.ts +9 -0
- package/dist/bus/serializers/index.js +14 -0
- package/dist/bus/serializers/json.d.ts +77 -0
- package/dist/bus/serializers/json.js +367 -0
- package/dist/bus/subscriber.d.ts +46 -0
- package/dist/bus/subscriber.js +27 -0
- package/dist/bus/ui/index.d.ts +3 -0
- package/dist/bus/ui/index.js +8 -0
- package/dist/bus/ui/messages.d.ts +186 -0
- package/dist/bus/ui/messages.js +171 -0
- package/dist/classifiers/base_classifier.d.ts +263 -0
- package/dist/classifiers/base_classifier.js +346 -0
- package/dist/classifiers/cloudflare/clef/classifier.d.ts +70 -0
- package/dist/classifiers/cloudflare/clef/classifier.js +204 -0
- package/dist/classifiers/cloudflare/clef/client.d.ts +104 -0
- package/dist/classifiers/cloudflare/clef/client.js +234 -0
- package/dist/classifiers/cloudflare/clef/index.d.ts +2 -0
- package/dist/classifiers/cloudflare/clef/index.js +8 -0
- package/dist/classifiers/cloudflare/index.d.ts +2 -0
- package/dist/classifiers/cloudflare/index.js +8 -0
- package/dist/classifiers/http_client.d.ts +70 -0
- package/dist/classifiers/http_client.js +161 -0
- package/dist/classifiers/index.d.ts +2 -0
- package/dist/classifiers/index.js +8 -0
- package/dist/classifiers/jev/classifier.d.ts +8 -0
- package/dist/classifiers/jev/classifier.js +13 -0
- package/dist/classifiers/jev/client.d.ts +8 -0
- package/dist/classifiers/jev/client.js +13 -0
- package/dist/classifiers/jev/index.d.ts +2 -0
- package/dist/classifiers/jev/index.js +8 -0
- package/dist/classifiers/llm/classifier.d.ts +72 -0
- package/dist/classifiers/llm/classifier.js +304 -0
- package/dist/classifiers/llm/index.d.ts +2 -0
- package/dist/classifiers/llm/index.js +8 -0
- package/dist/classifiers/openai/decisions/classifier.d.ts +77 -0
- package/dist/classifiers/openai/decisions/classifier.js +241 -0
- package/dist/classifiers/openai/decisions/client.d.ts +108 -0
- package/dist/classifiers/openai/decisions/client.js +234 -0
- package/dist/classifiers/openai/decisions/index.d.ts +2 -0
- package/dist/classifiers/openai/decisions/index.js +8 -0
- package/dist/classifiers/openai/index.d.ts +2 -0
- package/dist/classifiers/openai/index.js +8 -0
- package/dist/classifiers/typesafe/index.d.ts +2 -0
- package/dist/classifiers/typesafe/index.js +8 -0
- package/dist/classifiers/typesafe/jev/classifier.d.ts +70 -0
- package/dist/classifiers/typesafe/jev/classifier.js +220 -0
- package/dist/classifiers/typesafe/jev/client.d.ts +105 -0
- package/dist/classifiers/typesafe/jev/client.js +233 -0
- package/dist/classifiers/typesafe/jev/index.d.ts +2 -0
- package/dist/classifiers/typesafe/jev/index.js +8 -0
- package/dist/clocks/base_clock.d.ts +13 -0
- package/dist/clocks/base_clock.js +14 -0
- package/dist/clocks/index.d.ts +2 -0
- package/dist/clocks/index.js +8 -0
- package/dist/clocks/system_clock.d.ts +15 -0
- package/dist/clocks/system_clock.js +25 -0
- package/dist/frames/frames.d.ts +2533 -0
- package/dist/frames/frames.js +2485 -0
- package/dist/frames/index.d.ts +2 -0
- package/dist/frames/index.js +8 -0
- package/dist/frames/protobufs/frames_pb2.d.ts +229 -0
- package/dist/frames/protobufs/frames_pb2.js +466 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +56 -0
- package/dist/metrics/index.d.ts +2 -0
- package/dist/metrics/index.js +8 -0
- package/dist/metrics/metrics.d.ts +276 -0
- package/dist/metrics/metrics.js +254 -0
- package/dist/observers/base_observer.d.ts +173 -0
- package/dist/observers/base_observer.js +151 -0
- package/dist/observers/error_observer.d.ts +75 -0
- package/dist/observers/error_observer.js +87 -0
- package/dist/observers/function_call_observer.d.ts +157 -0
- package/dist/observers/function_call_observer.js +222 -0
- package/dist/observers/index.d.ts +2 -0
- package/dist/observers/index.js +8 -0
- package/dist/observers/loggers/debug_log_observer.d.ts +91 -0
- package/dist/observers/loggers/debug_log_observer.js +228 -0
- package/dist/observers/loggers/index.d.ts +2 -0
- package/dist/observers/loggers/index.js +8 -0
- package/dist/observers/loggers/llm_log_observer.d.ts +24 -0
- package/dist/observers/loggers/llm_log_observer.js +110 -0
- package/dist/observers/loggers/metrics_log_observer.d.ts +85 -0
- package/dist/observers/loggers/metrics_log_observer.js +186 -0
- package/dist/observers/loggers/transcription_log_observer.d.ts +23 -0
- package/dist/observers/loggers/transcription_log_observer.js +74 -0
- package/dist/observers/service_metrics_observer.d.ts +168 -0
- package/dist/observers/service_metrics_observer.js +236 -0
- package/dist/observers/speaking_observer.d.ts +104 -0
- package/dist/observers/speaking_observer.js +150 -0
- package/dist/observers/startup_timing_observer.d.ts +221 -0
- package/dist/observers/startup_timing_observer.js +365 -0
- package/dist/observers/turn_tracking_observer.d.ts +78 -0
- package/dist/observers/turn_tracking_observer.js +189 -0
- package/dist/observers/user_bot_latency_observer.d.ts +411 -0
- package/dist/observers/user_bot_latency_observer.js +974 -0
- package/dist/pipeline/base_pipeline.d.ts +49 -0
- package/dist/pipeline/base_pipeline.js +101 -0
- package/dist/pipeline/capabilities.d.ts +76 -0
- package/dist/pipeline/capabilities.js +97 -0
- package/dist/pipeline/index.d.ts +2 -0
- package/dist/pipeline/index.js +8 -0
- package/dist/pipeline/job_context.d.ts +317 -0
- package/dist/pipeline/job_context.js +450 -0
- package/dist/pipeline/job_decorator.d.ts +54 -0
- package/dist/pipeline/job_decorator.js +92 -0
- package/dist/pipeline/llm_switcher.d.ts +84 -0
- package/dist/pipeline/llm_switcher.js +107 -0
- package/dist/pipeline/llm_with_backend.d.ts +435 -0
- package/dist/pipeline/llm_with_backend.js +806 -0
- package/dist/pipeline/parallel_pipeline.d.ts +83 -0
- package/dist/pipeline/parallel_pipeline.js +200 -0
- package/dist/pipeline/pipeline.d.ts +126 -0
- package/dist/pipeline/pipeline.js +196 -0
- package/dist/pipeline/service_switcher.d.ts +287 -0
- package/dist/pipeline/service_switcher.js +509 -0
- package/dist/pipeline/sync_parallel_pipeline.d.ts +192 -0
- package/dist/pipeline/sync_parallel_pipeline.js +387 -0
- package/dist/pipeline/worker.d.ts +821 -0
- package/dist/pipeline/worker.js +1656 -0
- package/dist/pipeline/worker_observer.d.ts +131 -0
- package/dist/pipeline/worker_observer.js +274 -0
- package/dist/pipeline/worker_ready_decorator.d.ts +45 -0
- package/dist/pipeline/worker_ready_decorator.js +76 -0
- package/dist/processors/aggregators/async_tool_messages.d.ts +146 -0
- package/dist/processors/aggregators/async_tool_messages.js +291 -0
- package/dist/processors/aggregators/dtmf_aggregator.d.ts +61 -0
- package/dist/processors/aggregators/dtmf_aggregator.js +144 -0
- package/dist/processors/aggregators/gated.d.ts +43 -0
- package/dist/processors/aggregators/gated.js +86 -0
- package/dist/processors/aggregators/gated_llm_context.d.ts +42 -0
- package/dist/processors/aggregators/gated_llm_context.js +86 -0
- package/dist/processors/aggregators/index.d.ts +2 -0
- package/dist/processors/aggregators/index.js +8 -0
- package/dist/processors/aggregators/llm_context.d.ts +370 -0
- package/dist/processors/aggregators/llm_context.js +580 -0
- package/dist/processors/aggregators/llm_context_summarizer.d.ts +219 -0
- package/dist/processors/aggregators/llm_context_summarizer.js +447 -0
- package/dist/processors/aggregators/llm_response.d.ts +37 -0
- package/dist/processors/aggregators/llm_response.js +71 -0
- package/dist/processors/aggregators/llm_response_universal.d.ts +966 -0
- package/dist/processors/aggregators/llm_response_universal.js +2394 -0
- package/dist/processors/aggregators/llm_text_processor.d.ts +53 -0
- package/dist/processors/aggregators/llm_text_processor.js +102 -0
- package/dist/processors/aggregators/sentence.d.ts +39 -0
- package/dist/processors/aggregators/sentence.js +69 -0
- package/dist/processors/async_generator.d.ts +42 -0
- package/dist/processors/async_generator.js +76 -0
- package/dist/processors/audio/audio_buffer_processor.d.ts +241 -0
- package/dist/processors/audio/audio_buffer_processor.js +565 -0
- package/dist/processors/audio/index.d.ts +2 -0
- package/dist/processors/audio/index.js +8 -0
- package/dist/processors/audio/vad_processor.d.ts +67 -0
- package/dist/processors/audio/vad_processor.js +103 -0
- package/dist/processors/consumer_processor.d.ts +49 -0
- package/dist/processors/consumer_processor.js +85 -0
- package/dist/processors/filters/frame_filter.d.ts +39 -0
- package/dist/processors/filters/frame_filter.js +52 -0
- package/dist/processors/filters/function_filter.d.ts +59 -0
- package/dist/processors/filters/function_filter.js +78 -0
- package/dist/processors/filters/identity_filter.d.ts +33 -0
- package/dist/processors/filters/identity_filter.js +37 -0
- package/dist/processors/filters/index.d.ts +2 -0
- package/dist/processors/filters/index.js +8 -0
- package/dist/processors/filters/null_filter.d.ts +34 -0
- package/dist/processors/filters/null_filter.js +47 -0
- package/dist/processors/filters/wake_notifier_filter.d.ts +48 -0
- package/dist/processors/filters/wake_notifier_filter.js +49 -0
- package/dist/processors/frame_processor.d.ts +360 -0
- package/dist/processors/frame_processor.js +932 -0
- package/dist/processors/frameworks/index.d.ts +2 -0
- package/dist/processors/frameworks/index.js +8 -0
- package/dist/processors/frameworks/rtvi/frames.d.ts +241 -0
- package/dist/processors/frameworks/rtvi/frames.js +259 -0
- package/dist/processors/frameworks/rtvi/index.d.ts +6 -0
- package/dist/processors/frameworks/rtvi/index.js +11 -0
- package/dist/processors/frameworks/rtvi/models.d.ts +1741 -0
- package/dist/processors/frameworks/rtvi/models.js +1807 -0
- package/dist/processors/frameworks/rtvi/observer.d.ts +340 -0
- package/dist/processors/frameworks/rtvi/observer.js +1113 -0
- package/dist/processors/frameworks/rtvi/processor.d.ts +182 -0
- package/dist/processors/frameworks/rtvi/processor.js +676 -0
- package/dist/processors/idle_frame_processor.d.ts +44 -0
- package/dist/processors/idle_frame_processor.js +86 -0
- package/dist/processors/index.d.ts +2 -0
- package/dist/processors/index.js +8 -0
- package/dist/processors/logger.d.ts +42 -0
- package/dist/processors/logger.js +87 -0
- package/dist/processors/metrics/frame_processor_metrics.d.ts +172 -0
- package/dist/processors/metrics/frame_processor_metrics.js +372 -0
- package/dist/processors/metrics/index.d.ts +2 -0
- package/dist/processors/metrics/index.js +8 -0
- package/dist/processors/producer_processor.d.ts +68 -0
- package/dist/processors/producer_processor.js +78 -0
- package/dist/processors/text_transformer.d.ts +30 -0
- package/dist/processors/text_transformer.js +48 -0
- package/dist/registry/index.d.ts +3 -0
- package/dist/registry/index.js +8 -0
- package/dist/registry/registry.d.ts +69 -0
- package/dist/registry/registry.js +149 -0
- package/dist/registry/types.d.ts +47 -0
- package/dist/registry/types.js +39 -0
- package/dist/serializers/base_serializer.d.ts +94 -0
- package/dist/serializers/base_serializer.js +82 -0
- package/dist/serializers/index.d.ts +2 -0
- package/dist/serializers/index.js +8 -0
- package/dist/services/ai_service.d.ts +145 -0
- package/dist/services/ai_service.js +262 -0
- package/dist/services/anthropic/index.d.ts +2 -0
- package/dist/services/anthropic/index.js +7 -0
- package/dist/services/assemblyai/index.d.ts +2 -0
- package/dist/services/assemblyai/index.js +7 -0
- package/dist/services/asyncai/index.d.ts +2 -0
- package/dist/services/asyncai/index.js +7 -0
- package/dist/services/aws/index.d.ts +2 -0
- package/dist/services/aws/index.js +7 -0
- package/dist/services/azure/index.d.ts +2 -0
- package/dist/services/azure/index.js +7 -0
- package/dist/services/baseten/index.d.ts +2 -0
- package/dist/services/baseten/index.js +7 -0
- package/dist/services/bland/index.d.ts +2 -0
- package/dist/services/bland/index.js +7 -0
- package/dist/services/camb/index.d.ts +2 -0
- package/dist/services/camb/index.js +7 -0
- package/dist/services/cartesia/index.d.ts +2 -0
- package/dist/services/cartesia/index.js +7 -0
- package/dist/services/cerebras/index.d.ts +2 -0
- package/dist/services/cerebras/index.js +7 -0
- package/dist/services/crusoe/index.d.ts +2 -0
- package/dist/services/crusoe/index.js +7 -0
- package/dist/services/deepgram/index.d.ts +2 -0
- package/dist/services/deepgram/index.js +7 -0
- package/dist/services/deepseek/index.d.ts +2 -0
- package/dist/services/deepseek/index.js +7 -0
- package/dist/services/elevenlabs/index.d.ts +2 -0
- package/dist/services/elevenlabs/index.js +7 -0
- package/dist/services/fal/index.d.ts +2 -0
- package/dist/services/fal/index.js +7 -0
- package/dist/services/fireworks/index.d.ts +2 -0
- package/dist/services/fireworks/index.js +7 -0
- package/dist/services/fish/index.d.ts +2 -0
- package/dist/services/fish/index.js +7 -0
- package/dist/services/funasr/index.d.ts +3 -0
- package/dist/services/funasr/index.js +8 -0
- package/dist/services/gladia/index.d.ts +2 -0
- package/dist/services/gladia/index.js +7 -0
- package/dist/services/google/index.d.ts +2 -0
- package/dist/services/google/index.js +7 -0
- package/dist/services/gradium/index.d.ts +2 -0
- package/dist/services/gradium/index.js +7 -0
- package/dist/services/grok/index.d.ts +2 -0
- package/dist/services/grok/index.js +7 -0
- package/dist/services/groq/index.d.ts +2 -0
- package/dist/services/groq/index.js +7 -0
- package/dist/services/heygen/index.d.ts +2 -0
- package/dist/services/heygen/index.js +7 -0
- package/dist/services/hume/index.d.ts +2 -0
- package/dist/services/hume/index.js +7 -0
- package/dist/services/image_service.d.ts +52 -0
- package/dist/services/image_service.js +60 -0
- package/dist/services/inception/index.d.ts +2 -0
- package/dist/services/inception/index.js +7 -0
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.js +8 -0
- package/dist/services/inworld/index.d.ts +2 -0
- package/dist/services/inworld/index.js +7 -0
- package/dist/services/keenable/index.d.ts +2 -0
- package/dist/services/keenable/index.js +7 -0
- package/dist/services/kokoro/index.d.ts +2 -0
- package/dist/services/kokoro/index.js +7 -0
- package/dist/services/llm_service.d.ts +1106 -0
- package/dist/services/llm_service.js +2231 -0
- package/dist/services/mem0/index.d.ts +2 -0
- package/dist/services/mem0/index.js +7 -0
- package/dist/services/meta/index.d.ts +2 -0
- package/dist/services/meta/index.js +7 -0
- package/dist/services/minimax/index.d.ts +2 -0
- package/dist/services/minimax/index.js +7 -0
- package/dist/services/mistral/index.d.ts +2 -0
- package/dist/services/mistral/index.js +7 -0
- package/dist/services/moondream/index.d.ts +2 -0
- package/dist/services/moondream/index.js +7 -0
- package/dist/services/moonshine/index.d.ts +2 -0
- package/dist/services/moonshine/index.js +7 -0
- package/dist/services/nebius/index.d.ts +2 -0
- package/dist/services/nebius/index.js +7 -0
- package/dist/services/neuphonic/index.d.ts +2 -0
- package/dist/services/neuphonic/index.js +7 -0
- package/dist/services/novita/index.d.ts +2 -0
- package/dist/services/novita/index.js +7 -0
- package/dist/services/nvidia/index.d.ts +2 -0
- package/dist/services/nvidia/index.js +11 -0
- package/dist/services/ollama/index.d.ts +2 -0
- package/dist/services/ollama/index.js +7 -0
- package/dist/services/openai/index.d.ts +2 -0
- package/dist/services/openai/index.js +7 -0
- package/dist/services/openclaw/index.d.ts +14 -0
- package/dist/services/openclaw/index.js +19 -0
- package/dist/services/openrouter/index.d.ts +2 -0
- package/dist/services/openrouter/index.js +7 -0
- package/dist/services/perplexity/index.d.ts +2 -0
- package/dist/services/perplexity/index.js +7 -0
- package/dist/services/piper/index.d.ts +2 -0
- package/dist/services/piper/index.js +7 -0
- package/dist/services/pocket_tts/index.d.ts +2 -0
- package/dist/services/pocket_tts/index.js +7 -0
- package/dist/services/qwen/index.d.ts +2 -0
- package/dist/services/qwen/index.js +7 -0
- package/dist/services/resembleai/index.d.ts +2 -0
- package/dist/services/resembleai/index.js +7 -0
- package/dist/services/rime/index.d.ts +2 -0
- package/dist/services/rime/index.js +7 -0
- package/dist/services/sambanova/index.d.ts +2 -0
- package/dist/services/sambanova/index.js +7 -0
- package/dist/services/sarvam/index.d.ts +2 -0
- package/dist/services/sarvam/index.js +7 -0
- package/dist/services/settings.d.ts +356 -0
- package/dist/services/settings.js +437 -0
- package/dist/services/simli/index.d.ts +2 -0
- package/dist/services/simli/index.js +7 -0
- package/dist/services/smallest/index.d.ts +2 -0
- package/dist/services/smallest/index.js +7 -0
- package/dist/services/soniox/index.d.ts +2 -0
- package/dist/services/soniox/index.js +7 -0
- package/dist/services/speechify/index.d.ts +2 -0
- package/dist/services/speechify/index.js +7 -0
- package/dist/services/speechmatics/index.d.ts +2 -0
- package/dist/services/speechmatics/index.js +7 -0
- package/dist/services/stt_latency.d.ts +62 -0
- package/dist/services/stt_latency.js +71 -0
- package/dist/services/stt_service.d.ts +601 -0
- package/dist/services/stt_service.js +1044 -0
- package/dist/services/tavus/index.d.ts +2 -0
- package/dist/services/tavus/index.js +7 -0
- package/dist/services/together/index.d.ts +2 -0
- package/dist/services/together/index.js +7 -0
- package/dist/services/tts_service.d.ts +909 -0
- package/dist/services/tts_service.js +2018 -0
- package/dist/services/ultravox/index.d.ts +2 -0
- package/dist/services/ultravox/index.js +9 -0
- package/dist/services/vision_service.d.ts +56 -0
- package/dist/services/vision_service.js +62 -0
- package/dist/services/websocket_service.d.ts +213 -0
- package/dist/services/websocket_service.js +654 -0
- package/dist/services/whisper/index.d.ts +2 -0
- package/dist/services/whisper/index.js +9 -0
- package/dist/services/xai/index.d.ts +2 -0
- package/dist/services/xai/index.js +9 -0
- package/dist/services/xtts/index.d.ts +2 -0
- package/dist/services/xtts/index.js +9 -0
- package/dist/tests/index.d.ts +2 -0
- package/dist/tests/index.js +8 -0
- package/dist/tests/utils.d.ts +123 -0
- package/dist/tests/utils.js +212 -0
- package/dist/transcriptions/index.d.ts +2 -0
- package/dist/transcriptions/index.js +8 -0
- package/dist/transcriptions/language.d.ts +376 -0
- package/dist/transcriptions/language.js +543 -0
- package/dist/transports/base_input.d.ts +149 -0
- package/dist/transports/base_input.js +338 -0
- package/dist/transports/base_output.d.ts +432 -0
- package/dist/transports/base_output.js +1231 -0
- package/dist/transports/base_transport.d.ts +223 -0
- package/dist/transports/base_transport.js +167 -0
- package/dist/transports/daily/index.d.ts +2 -0
- package/dist/transports/daily/index.js +9 -0
- package/dist/transports/heygen/index.d.ts +2 -0
- package/dist/transports/heygen/index.js +9 -0
- package/dist/transports/index.d.ts +2 -0
- package/dist/transports/index.js +8 -0
- package/dist/transports/lemonslice/index.d.ts +2 -0
- package/dist/transports/lemonslice/index.js +9 -0
- package/dist/transports/livekit/index.d.ts +2 -0
- package/dist/transports/livekit/index.js +9 -0
- package/dist/transports/local/index.d.ts +2 -0
- package/dist/transports/local/index.js +9 -0
- package/dist/transports/moq/index.d.ts +2 -0
- package/dist/transports/moq/index.js +9 -0
- package/dist/transports/smallwebrtc/index.d.ts +2 -0
- package/dist/transports/smallwebrtc/index.js +9 -0
- package/dist/transports/tavus/index.d.ts +2 -0
- package/dist/transports/tavus/index.js +9 -0
- package/dist/transports/video_in_sampler.d.ts +157 -0
- package/dist/transports/video_in_sampler.js +258 -0
- package/dist/transports/vonage/index.d.ts +2 -0
- package/dist/transports/vonage/index.js +9 -0
- package/dist/transports/websocket/index.d.ts +2 -0
- package/dist/transports/websocket/index.js +9 -0
- package/dist/transports/whatsapp/index.d.ts +2 -0
- package/dist/transports/whatsapp/index.js +9 -0
- package/dist/turns/eager_end_of_turn_mixin.d.ts +70 -0
- package/dist/turns/eager_end_of_turn_mixin.js +122 -0
- package/dist/turns/empty_user_turn.d.ts +55 -0
- package/dist/turns/empty_user_turn.js +53 -0
- package/dist/turns/index.d.ts +2 -0
- package/dist/turns/index.js +8 -0
- package/dist/turns/speculation_gate.d.ts +169 -0
- package/dist/turns/speculation_gate.js +294 -0
- package/dist/turns/types.d.ts +33 -0
- package/dist/turns/types.js +35 -0
- package/dist/turns/user_idle_controller.d.ts +94 -0
- package/dist/turns/user_idle_controller.js +187 -0
- package/dist/turns/user_mute/always_user_mute_strategy.d.ts +15 -0
- package/dist/turns/user_mute/always_user_mute_strategy.js +29 -0
- package/dist/turns/user_mute/base_user_mute_strategy.d.ts +39 -0
- package/dist/turns/user_mute/base_user_mute_strategy.js +45 -0
- package/dist/turns/user_mute/first_speech_user_mute_strategy.d.ts +28 -0
- package/dist/turns/user_mute/first_speech_user_mute_strategy.js +52 -0
- package/dist/turns/user_mute/function_call_user_mute_strategy.d.ts +25 -0
- package/dist/turns/user_mute/function_call_user_mute_strategy.js +50 -0
- package/dist/turns/user_mute/index.d.ts +6 -0
- package/dist/turns/user_mute/index.js +11 -0
- package/dist/turns/user_mute/mute_until_first_bot_complete_user_mute_strategy.d.ts +43 -0
- package/dist/turns/user_mute/mute_until_first_bot_complete_user_mute_strategy.js +76 -0
- package/dist/turns/user_start/base_user_turn_start_strategy.d.ts +135 -0
- package/dist/turns/user_start/base_user_turn_start_strategy.js +134 -0
- package/dist/turns/user_start/external_user_turn_start_strategy.d.ts +45 -0
- package/dist/turns/user_start/external_user_turn_start_strategy.js +64 -0
- package/dist/turns/user_start/index.d.ts +8 -0
- package/dist/turns/user_start/index.js +16 -0
- package/dist/turns/user_start/krisp_viva_ip_user_turn_start_strategy.d.ts +133 -0
- package/dist/turns/user_start/krisp_viva_ip_user_turn_start_strategy.js +243 -0
- package/dist/turns/user_start/min_words_user_turn_start_strategy.d.ts +60 -0
- package/dist/turns/user_start/min_words_user_turn_start_strategy.js +102 -0
- package/dist/turns/user_start/transcription_user_turn_start_strategy.d.ts +29 -0
- package/dist/turns/user_start/transcription_user_turn_start_strategy.js +43 -0
- package/dist/turns/user_start/vad_user_turn_start_strategy.d.ts +20 -0
- package/dist/turns/user_start/vad_user_turn_start_strategy.js +31 -0
- package/dist/turns/user_start/wake_phrase_user_turn_start_strategy.d.ts +141 -0
- package/dist/turns/user_start/wake_phrase_user_turn_start_strategy.js +238 -0
- package/dist/turns/user_stop/base_user_turn_stop_strategy.d.ts +174 -0
- package/dist/turns/user_stop/base_user_turn_stop_strategy.js +170 -0
- package/dist/turns/user_stop/deferred_user_turn_stop_strategy.d.ts +81 -0
- package/dist/turns/user_stop/deferred_user_turn_stop_strategy.js +107 -0
- package/dist/turns/user_stop/eager_match_policy.d.ts +36 -0
- package/dist/turns/user_stop/eager_match_policy.js +50 -0
- package/dist/turns/user_stop/eager_user_turn_stop_strategy.d.ts +84 -0
- package/dist/turns/user_stop/eager_user_turn_stop_strategy.js +154 -0
- package/dist/turns/user_stop/external_user_turn_completion_stop_strategy.d.ts +45 -0
- package/dist/turns/user_stop/external_user_turn_completion_stop_strategy.js +55 -0
- package/dist/turns/user_stop/external_user_turn_stop_strategy.d.ts +115 -0
- package/dist/turns/user_stop/external_user_turn_stop_strategy.js +205 -0
- package/dist/turns/user_stop/index.d.ts +10 -0
- package/dist/turns/user_stop/index.js +15 -0
- package/dist/turns/user_stop/llm_turn_completion_user_turn_stop_strategy.d.ts +44 -0
- package/dist/turns/user_stop/llm_turn_completion_user_turn_stop_strategy.js +59 -0
- package/dist/turns/user_stop/speech_timeout_user_turn_stop_strategy.d.ts +140 -0
- package/dist/turns/user_stop/speech_timeout_user_turn_stop_strategy.js +303 -0
- package/dist/turns/user_stop/turn_analyzer_user_turn_stop_strategy.d.ts +135 -0
- package/dist/turns/user_stop/turn_analyzer_user_turn_stop_strategy.js +332 -0
- package/dist/turns/user_turn_completion_mixin.d.ts +147 -0
- package/dist/turns/user_turn_completion_mixin.js +591 -0
- package/dist/turns/user_turn_controller.d.ts +134 -0
- package/dist/turns/user_turn_controller.js +335 -0
- package/dist/turns/user_turn_processor.d.ts +87 -0
- package/dist/turns/user_turn_processor.js +180 -0
- package/dist/turns/user_turn_strategies.d.ts +187 -0
- package/dist/turns/user_turn_strategies.js +222 -0
- package/dist/utils/async_tool_cancellation.d.ts +35 -0
- package/dist/utils/async_tool_cancellation.js +78 -0
- package/dist/utils/asyncio/index.d.ts +2 -0
- package/dist/utils/asyncio/index.js +7 -0
- package/dist/utils/asyncio/task_manager.d.ts +49 -0
- package/dist/utils/asyncio/task_manager.js +105 -0
- package/dist/utils/base_object.d.ts +76 -0
- package/dist/utils/base_object.js +154 -0
- package/dist/utils/context/aggregated_frame_sequencer.d.ts +491 -0
- package/dist/utils/context/aggregated_frame_sequencer.js +803 -0
- package/dist/utils/context/audio_context_manager.d.ts +131 -0
- package/dist/utils/context/audio_context_manager.js +233 -0
- package/dist/utils/context/index.d.ts +2 -0
- package/dist/utils/context/index.js +7 -0
- package/dist/utils/context/llm_context_summarization.d.ts +258 -0
- package/dist/utils/context/llm_context_summarization.js +511 -0
- package/dist/utils/context/text_segment_map.d.ts +611 -0
- package/dist/utils/context/text_segment_map.js +1132 -0
- package/dist/utils/context/word_completion_tracker.d.ts +273 -0
- package/dist/utils/context/word_completion_tracker.js +441 -0
- package/dist/utils/context/word_timestamp_tracker.d.ts +72 -0
- package/dist/utils/context/word_timestamp_tracker.js +98 -0
- package/dist/utils/deprecation.d.ts +28 -0
- package/dist/utils/deprecation.js +75 -0
- package/dist/utils/env.d.ts +38 -0
- package/dist/utils/env.js +62 -0
- package/dist/utils/errors.d.ts +75 -0
- package/dist/utils/errors.js +202 -0
- package/dist/utils/file_resolver.d.ts +126 -0
- package/dist/utils/file_resolver.js +314 -0
- package/dist/utils/file_storage.d.ts +115 -0
- package/dist/utils/file_storage.js +178 -0
- package/dist/utils/frame_queue.d.ts +36 -0
- package/dist/utils/frame_queue.js +66 -0
- package/dist/utils/http.d.ts +39 -0
- package/dist/utils/http.js +53 -0
- package/dist/utils/image.d.ts +14 -0
- package/dist/utils/image.js +63 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/jpeg_encoder.d.ts +14 -0
- package/dist/utils/jpeg_encoder.js +315 -0
- package/dist/utils/log_config.d.ts +34 -0
- package/dist/utils/log_config.js +76 -0
- package/dist/utils/logger.d.ts +40 -0
- package/dist/utils/logger.js +91 -0
- package/dist/utils/mixin.d.ts +14 -0
- package/dist/utils/mixin.js +63 -0
- package/dist/utils/network.d.ts +73 -0
- package/dist/utils/network.js +90 -0
- package/dist/utils/security/allowed_origins.d.ts +16 -0
- package/dist/utils/security/allowed_origins.js +34 -0
- package/dist/utils/security/index.d.ts +2 -0
- package/dist/utils/security/index.js +7 -0
- package/dist/utils/security/redaction.d.ts +27 -0
- package/dist/utils/security/redaction.js +123 -0
- package/dist/utils/security/ssrf.d.ts +79 -0
- package/dist/utils/security/ssrf.js +327 -0
- package/dist/utils/shared.d.ts +35 -0
- package/dist/utils/shared.js +136 -0
- package/dist/utils/startup.d.ts +17 -0
- package/dist/utils/startup.js +130 -0
- package/dist/utils/string.d.ts +116 -0
- package/dist/utils/string.js +460 -0
- package/dist/utils/sync/base_notifier.d.ts +25 -0
- package/dist/utils/sync/base_notifier.js +16 -0
- package/dist/utils/sync/event_notifier.d.ts +38 -0
- package/dist/utils/sync/event_notifier.js +51 -0
- package/dist/utils/sync/index.d.ts +2 -0
- package/dist/utils/sync/index.js +7 -0
- package/dist/utils/text/alnum_utils.d.ts +109 -0
- package/dist/utils/text/alnum_utils.js +262 -0
- package/dist/utils/text/base_text_aggregator.d.ts +146 -0
- package/dist/utils/text/base_text_aggregator.js +102 -0
- package/dist/utils/text/base_text_filter.d.ts +54 -0
- package/dist/utils/text/base_text_filter.js +50 -0
- package/dist/utils/text/index.d.ts +2 -0
- package/dist/utils/text/index.js +7 -0
- package/dist/utils/text/markdown_text_filter.d.ts +147 -0
- package/dist/utils/text/markdown_text_filter.js +522 -0
- package/dist/utils/text/markup_utils.d.ts +54 -0
- package/dist/utils/text/markup_utils.js +156 -0
- package/dist/utils/text/pattern_pair_aggregator.d.ts +251 -0
- package/dist/utils/text/pattern_pair_aggregator.js +478 -0
- package/dist/utils/text/phonemes.d.ts +60 -0
- package/dist/utils/text/phonemes.js +172 -0
- package/dist/utils/text/simple_text_aggregator.d.ts +135 -0
- package/dist/utils/text/simple_text_aggregator.js +254 -0
- package/dist/utils/text/skip_tags_aggregator.d.ts +85 -0
- package/dist/utils/text/skip_tags_aggregator.js +147 -0
- package/dist/utils/text/transforms/acronyms.d.ts +21 -0
- package/dist/utils/text/transforms/acronyms.js +31 -0
- package/dist/utils/text/transforms/currency.d.ts +16 -0
- package/dist/utils/text/transforms/currency.js +56 -0
- package/dist/utils/text/transforms/dates.d.ts +18 -0
- package/dist/utils/text/transforms/dates.js +102 -0
- package/dist/utils/text/transforms/email.d.ts +17 -0
- package/dist/utils/text/transforms/email.js +35 -0
- package/dist/utils/text/transforms/index.d.ts +37 -0
- package/dist/utils/text/transforms/index.js +42 -0
- package/dist/utils/text/transforms/numbers.d.ts +25 -0
- package/dist/utils/text/transforms/numbers.js +59 -0
- package/dist/utils/text/transforms/percentages.d.ts +16 -0
- package/dist/utils/text/transforms/percentages.js +32 -0
- package/dist/utils/text/transforms/phone.d.ts +21 -0
- package/dist/utils/text/transforms/phone.js +39 -0
- package/dist/utils/text/transforms/pronunciations.d.ts +65 -0
- package/dist/utils/text/transforms/pronunciations.js +112 -0
- package/dist/utils/text/transforms/replacements.d.ts +39 -0
- package/dist/utils/text/transforms/replacements.js +46 -0
- package/dist/utils/text/transforms/strip_markdown.d.ts +25 -0
- package/dist/utils/text/transforms/strip_markdown.js +60 -0
- package/dist/utils/text/transforms/units.d.ts +22 -0
- package/dist/utils/text/transforms/units.js +81 -0
- package/dist/utils/text/transforms/voice_formatter.d.ts +86 -0
- package/dist/utils/text/transforms/voice_formatter.js +98 -0
- package/dist/utils/text/unicode_digits.d.ts +3 -0
- package/dist/utils/text/unicode_digits.js +34 -0
- package/dist/utils/text/word_timestamp_utils.d.ts +26 -0
- package/dist/utils/text/word_timestamp_utils.js +52 -0
- package/dist/utils/time.d.ts +13 -0
- package/dist/utils/time.js +31 -0
- package/dist/utils/tracing/index.d.ts +3 -0
- package/dist/utils/tracing/index.js +8 -0
- package/dist/utils/tracing/service_attributes.d.ts +198 -0
- package/dist/utils/tracing/service_attributes.js +434 -0
- package/dist/utils/tracing/service_decorators.d.ts +214 -0
- package/dist/utils/tracing/service_decorators.js +1662 -0
- package/dist/utils/tracing/setup.d.ts +107 -0
- package/dist/utils/tracing/setup.js +160 -0
- package/dist/utils/tracing/tracing_context.d.ts +55 -0
- package/dist/utils/tracing/tracing_context.js +97 -0
- package/dist/utils/tracing/turn_trace_observer.d.ts +95 -0
- package/dist/utils/tracing/turn_trace_observer.js +233 -0
- package/dist/utils/types.d.ts +80 -0
- package/dist/utils/types.js +108 -0
- package/dist/utils/utils.d.ts +5 -0
- package/dist/utils/utils.js +22 -0
- package/dist/utils/yaml.d.ts +179 -0
- package/dist/utils/yaml.js +556 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.js +7 -0
- package/dist/workers/base_worker.d.ts +772 -0
- package/dist/workers/base_worker.js +1298 -0
- package/dist/workers/index.d.ts +2 -0
- package/dist/workers/index.js +8 -0
- package/dist/workers/llm/backend_llm_worker.d.ts +552 -0
- package/dist/workers/llm/backend_llm_worker.js +1055 -0
- package/dist/workers/llm/index.d.ts +6 -0
- package/dist/workers/llm/index.js +11 -0
- package/dist/workers/llm/llm_context_worker.d.ts +66 -0
- package/dist/workers/llm/llm_context_worker.js +72 -0
- package/dist/workers/llm/llm_worker.d.ts +180 -0
- package/dist/workers/llm/llm_worker.js +323 -0
- package/dist/workers/llm/tool_decorator.d.ts +68 -0
- package/dist/workers/llm/tool_decorator.js +60 -0
- package/dist/workers/proxy/index.d.ts +3 -0
- package/dist/workers/proxy/index.js +9 -0
- package/dist/workers/proxy/websocket/client.d.ts +110 -0
- package/dist/workers/proxy/websocket/client.js +196 -0
- package/dist/workers/proxy/websocket/index.d.ts +3 -0
- package/dist/workers/proxy/websocket/index.js +10 -0
- package/dist/workers/runner.d.ts +268 -0
- package/dist/workers/runner.js +489 -0
- package/dist/workers/ui/index.d.ts +22 -0
- package/dist/workers/ui/index.js +27 -0
- package/dist/workers/ui/ui_event_decorator.d.ts +43 -0
- package/dist/workers/ui/ui_event_decorator.js +75 -0
- package/dist/workers/ui/ui_job_context.d.ts +12 -0
- package/dist/workers/ui/ui_job_context.js +17 -0
- package/dist/workers/ui/ui_prompts.d.ts +21 -0
- package/dist/workers/ui/ui_prompts.js +41 -0
- package/dist/workers/ui/ui_tools.d.ts +32 -0
- package/dist/workers/ui/ui_tools.js +112 -0
- package/dist/workers/ui/ui_worker.d.ts +571 -0
- package/dist/workers/ui/ui_worker.js +1156 -0
- package/package.json +61 -3
- package/README.md +0 -5
|
@@ -0,0 +1,932 @@
|
|
|
1
|
+
// Copyright (c) 2024-2026, Daily
|
|
2
|
+
// Copyright (c) 2026, pipedog contributors
|
|
3
|
+
// SPDX-License-Identifier: BSD-2-Clause
|
|
4
|
+
//
|
|
5
|
+
// Ported from pipecat: src/pipecat/processors/frame_processor.py
|
|
6
|
+
/**
|
|
7
|
+
* Frame processing pipeline infrastructure for Pipecat.
|
|
8
|
+
*
|
|
9
|
+
* Provides the core frame processing system that enables building
|
|
10
|
+
* audio/video processing pipelines: frame processors, pipeline management,
|
|
11
|
+
* and frame flow control mechanisms.
|
|
12
|
+
*/
|
|
13
|
+
import { Event, PriorityQueue, pythonCompare, rethrowIfCancelled, TimeoutError, waitFor, } from "@pipedog/asyncio";
|
|
14
|
+
import { CancelFrame, ErrorFrame, FrameProcessorPauseFrame, FrameProcessorPauseUrgentFrame, FrameProcessorResumeFrame, FrameProcessorResumeUrgentFrame, InterruptionFrame, renewFrameIdentity, StartFrame, SystemFrame, } from "../frames/frames.js";
|
|
15
|
+
import { FrameProcessed, FramePushed } from "../observers/base_observer.js";
|
|
16
|
+
import { BaseObject } from "../utils/base_object.js";
|
|
17
|
+
import { classifyHttpException, ErrorCategory } from "../utils/errors.js";
|
|
18
|
+
import { FrameQueue } from "../utils/frame_queue.js";
|
|
19
|
+
import { logger } from "../utils/logger.js";
|
|
20
|
+
import { FrameProcessorMetrics } from "./metrics/frame_processor_metrics.js";
|
|
21
|
+
/**
|
|
22
|
+
* Direction of frame flow in the processing pipeline.
|
|
23
|
+
*
|
|
24
|
+
* - DOWNSTREAM: frames flowing from input to output.
|
|
25
|
+
* - UPSTREAM: frames flowing back from output to input.
|
|
26
|
+
*/
|
|
27
|
+
export const FrameDirection = {
|
|
28
|
+
DOWNSTREAM: 1,
|
|
29
|
+
UPSTREAM: 2,
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Configuration parameters for frame processor initialization.
|
|
33
|
+
*
|
|
34
|
+
* - `audioInSampleRate` / `audioOutSampleRate`: audio sample rates in Hz.
|
|
35
|
+
* - `clock`: the clock instance for timing operations.
|
|
36
|
+
* - `enableMetrics` / `enableTracing` / `enableUsageMetrics`: feature switches.
|
|
37
|
+
* - `pipelineWorker`: the PipelineWorker running this pipeline, so processors
|
|
38
|
+
* can reach worker-scoped state (e.g. `this.pipelineWorker.appResources`).
|
|
39
|
+
* - `observer`: optional observer for monitoring frame processing events.
|
|
40
|
+
* - `taskManager`: the task manager for handling async operations.
|
|
41
|
+
* - `tracingContext`: pipeline-scoped tracing context for span hierarchy.
|
|
42
|
+
*/
|
|
43
|
+
export class FrameProcessorSetup {
|
|
44
|
+
clock;
|
|
45
|
+
taskManager;
|
|
46
|
+
pipelineWorker;
|
|
47
|
+
audioInSampleRate;
|
|
48
|
+
audioOutSampleRate;
|
|
49
|
+
enableMetrics;
|
|
50
|
+
enableTracing;
|
|
51
|
+
enableUsageMetrics;
|
|
52
|
+
observer;
|
|
53
|
+
reportOnlyInitialTtfb;
|
|
54
|
+
tracingContext;
|
|
55
|
+
constructor(options) {
|
|
56
|
+
this.clock = options.clock;
|
|
57
|
+
this.taskManager = options.taskManager;
|
|
58
|
+
this.pipelineWorker = options.pipelineWorker;
|
|
59
|
+
this.audioInSampleRate = options.audioInSampleRate ?? 16000;
|
|
60
|
+
this.audioOutSampleRate = options.audioOutSampleRate ?? 24000;
|
|
61
|
+
this.enableMetrics = options.enableMetrics ?? false;
|
|
62
|
+
this.enableTracing = options.enableTracing ?? false;
|
|
63
|
+
this.enableUsageMetrics = options.enableUsageMetrics ?? false;
|
|
64
|
+
this.observer = options.observer ?? null;
|
|
65
|
+
this.reportOnlyInitialTtfb = options.reportOnlyInitialTtfb ?? false;
|
|
66
|
+
this.tracingContext = options.tracingContext ?? null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* A priority queue for the frames arriving at a frame processor.
|
|
71
|
+
*
|
|
72
|
+
* Frames are dequeued in three tiers: the StartFrame first, then
|
|
73
|
+
* SystemFrame, then data and control frames. Frames of the same tier keep
|
|
74
|
+
* their arrival order.
|
|
75
|
+
*/
|
|
76
|
+
export class FrameProcessorQueue {
|
|
77
|
+
static START_PRIORITY = 1;
|
|
78
|
+
static SYSTEM_PRIORITY = 10;
|
|
79
|
+
static DEFAULT_PRIORITY = 20;
|
|
80
|
+
#queue = new PriorityQueue(0, (a, b) => pythonCompare([a[0], a[1]], [b[0], b[1]]));
|
|
81
|
+
// Counts every frame enqueued, which keeps frames of the same tier in
|
|
82
|
+
// arrival order and stops the queue from ever having to compare frames.
|
|
83
|
+
#counter = 0;
|
|
84
|
+
/**
|
|
85
|
+
* Put an item into the priority queue. The StartFrame outranks every other
|
|
86
|
+
* frame and SystemFrame frames outrank data and control frames.
|
|
87
|
+
*/
|
|
88
|
+
async put(item) {
|
|
89
|
+
const [frame] = item;
|
|
90
|
+
let priority;
|
|
91
|
+
if (frame instanceof StartFrame) {
|
|
92
|
+
priority = FrameProcessorQueue.START_PRIORITY;
|
|
93
|
+
}
|
|
94
|
+
else if (frame instanceof SystemFrame) {
|
|
95
|
+
priority = FrameProcessorQueue.SYSTEM_PRIORITY;
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
priority = FrameProcessorQueue.DEFAULT_PRIORITY;
|
|
99
|
+
}
|
|
100
|
+
this.#counter += 1;
|
|
101
|
+
await this.#queue.put([priority, this.#counter, item]);
|
|
102
|
+
}
|
|
103
|
+
/** Retrieve the next item from the queue, waiting until one is available. */
|
|
104
|
+
async get() {
|
|
105
|
+
const [, , item] = await this.#queue.get();
|
|
106
|
+
return item;
|
|
107
|
+
}
|
|
108
|
+
taskDone() {
|
|
109
|
+
this.#queue.taskDone();
|
|
110
|
+
}
|
|
111
|
+
empty() {
|
|
112
|
+
return this.#queue.empty();
|
|
113
|
+
}
|
|
114
|
+
qsize() {
|
|
115
|
+
return this.#queue.qsize();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* How long (seconds) a processor holds frames waiting for a readiness
|
|
120
|
+
* condition before giving up and resuming. See `pauseProcessingAllFramesUntil()`.
|
|
121
|
+
*/
|
|
122
|
+
export const PAUSE_UNTIL_READY_TIMEOUT_SECS = 5.0;
|
|
123
|
+
/**
|
|
124
|
+
* Timeout in seconds for cancelling the input frame processing task. Prevents
|
|
125
|
+
* hanging if some code swallows cancellation.
|
|
126
|
+
*/
|
|
127
|
+
export const INPUT_TASK_CANCEL_TIMEOUT_SECS = 3;
|
|
128
|
+
/**
|
|
129
|
+
* Base class for all frame processors in the pipeline.
|
|
130
|
+
*
|
|
131
|
+
* Frame processors are the building blocks of Pipecat pipelines. They
|
|
132
|
+
* receive frames, process them, and pass them to the next or previous
|
|
133
|
+
* processor in the chain. Each processor guarantees frame ordering and
|
|
134
|
+
* processes frames in its own task. System frames are processed in a
|
|
135
|
+
* separate task which guarantees frame priority.
|
|
136
|
+
*
|
|
137
|
+
* Event handlers available:
|
|
138
|
+
*
|
|
139
|
+
* - on_before_process_frame: called before a frame is processed
|
|
140
|
+
* - on_after_process_frame: called after a frame is processed
|
|
141
|
+
* - on_before_push_frame: called before a frame is pushed
|
|
142
|
+
* - on_after_push_frame: called after a frame is pushed
|
|
143
|
+
* - on_error: called when an error is raised in the frame processing
|
|
144
|
+
* - on_usable_changed: called with the new value of `isUsable` when the
|
|
145
|
+
* processor stops or starts being able to do its job
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* processor.eventHandler("on_usable_changed", async (processor, isUsable) => { ... });
|
|
149
|
+
*/
|
|
150
|
+
export class FrameProcessor extends BaseObject {
|
|
151
|
+
_prev = null;
|
|
152
|
+
_next = null;
|
|
153
|
+
// Enable direct mode to skip queues and process frames right away.
|
|
154
|
+
_enableDirectMode;
|
|
155
|
+
// Processor setup
|
|
156
|
+
_setup = null;
|
|
157
|
+
// Cancellation is done through CancelFrame (a system frame). This could
|
|
158
|
+
// cause other events being triggered (e.g. closing a transport) which could
|
|
159
|
+
// also cause other frames to be pushed from other tasks (e.g. EndFrame). So,
|
|
160
|
+
// when we are cancelling we don't want anything else to be pushed.
|
|
161
|
+
_cancelling = false;
|
|
162
|
+
// Metrics
|
|
163
|
+
_metrics;
|
|
164
|
+
// Processors have an input priority queue which stores any type of frames
|
|
165
|
+
// in order. System frames have higher priority than any other frames, so
|
|
166
|
+
// they will be returned first from the queue.
|
|
167
|
+
//
|
|
168
|
+
// If a system frame is obtained it will be processed immediately; any other
|
|
169
|
+
// type of frame (data and control) will be put in a separate queue for
|
|
170
|
+
// later processing. This guarantees that each frame processor will always
|
|
171
|
+
// process system frames before any other frame in the queue.
|
|
172
|
+
// The input task handles all types of frames. It processes system frames
|
|
173
|
+
// right away and queues non-system frames for later processing.
|
|
174
|
+
#shouldBlockSystemFrames = false;
|
|
175
|
+
#inputQueue = new FrameProcessorQueue();
|
|
176
|
+
#inputEvent = null;
|
|
177
|
+
#inputFrameTask = null;
|
|
178
|
+
// Watches the readiness condition passed to
|
|
179
|
+
// pauseProcessingAllFramesUntil() and lifts the pause it took.
|
|
180
|
+
#pauseWatcherTask = null;
|
|
181
|
+
// Clear while a pipeline is setting this processor up. The StartFrame is
|
|
182
|
+
// held until it is set, so a processor never starts before its own setup is
|
|
183
|
+
// done, while the ones ahead of it in the pipeline can.
|
|
184
|
+
#setupDone = new Event();
|
|
185
|
+
#startReceived = false;
|
|
186
|
+
// The process task processes non-system frames. Non-system frames will be
|
|
187
|
+
// processed as soon as they are received by the processing task (default)
|
|
188
|
+
// or they will block if `pauseProcessingFrames()` is called. To resume
|
|
189
|
+
// processing frames we need to call `resumeProcessingFrames()` which will
|
|
190
|
+
// wake up the event.
|
|
191
|
+
#shouldBlockFrames = false;
|
|
192
|
+
#processQueue = new FrameQueue((item) => item[0]);
|
|
193
|
+
#processEvent = null;
|
|
194
|
+
#processFrameTask = null;
|
|
195
|
+
#processCurrentFrame = null;
|
|
196
|
+
// Whether this processor can still do its job. Flipped by the errors it
|
|
197
|
+
// reports, so it is already up to date by the time an error travels.
|
|
198
|
+
_isUsable = true;
|
|
199
|
+
constructor(options = {}) {
|
|
200
|
+
super(options);
|
|
201
|
+
this._enableDirectMode = options.enableDirectMode ?? false;
|
|
202
|
+
this.#setupDone.set();
|
|
203
|
+
this._metrics = options.metrics ?? new FrameProcessorMetrics();
|
|
204
|
+
this._metrics.setProcessorName(this.name);
|
|
205
|
+
// Frame processor events.
|
|
206
|
+
this._registerEventHandler("on_before_process_frame", true);
|
|
207
|
+
this._registerEventHandler("on_after_process_frame", true);
|
|
208
|
+
this._registerEventHandler("on_before_push_frame", true);
|
|
209
|
+
this._registerEventHandler("on_after_push_frame", true);
|
|
210
|
+
this._registerEventHandler("on_error", true);
|
|
211
|
+
this._registerEventHandler("on_usable_changed");
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Whether this processor can still do its job.
|
|
215
|
+
*
|
|
216
|
+
* A processor stays usable through failures it might recover from, and
|
|
217
|
+
* becomes unusable once its work can no longer succeed: a provider has
|
|
218
|
+
* rejected its API key, model or voice, or it has failed enough times to
|
|
219
|
+
* stop trying. Services stop accepting work and stop reconnecting once this
|
|
220
|
+
* is false.
|
|
221
|
+
*
|
|
222
|
+
* Errors set this as they are reported, so an error handler reading
|
|
223
|
+
* `frame.processor.isUsable` sees the verdict that came with the error.
|
|
224
|
+
*/
|
|
225
|
+
get isUsable() {
|
|
226
|
+
return this._isUsable;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Set whether this processor can be given work. Call this to bring back a
|
|
230
|
+
* processor that became unusable, once whatever stopped it working has been
|
|
231
|
+
* dealt with.
|
|
232
|
+
*/
|
|
233
|
+
async setUsable(isUsable) {
|
|
234
|
+
if (isUsable === this._isUsable)
|
|
235
|
+
return;
|
|
236
|
+
this._isUsable = isUsable;
|
|
237
|
+
logger.debug(`${this}: ${isUsable ? "usable" : "no longer usable"}`);
|
|
238
|
+
await this._callEventHandler("on_usable_changed", isUsable);
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* The sub-processors contained within this processor. Only compound
|
|
242
|
+
* processors (e.g. pipelines and parallel pipelines) have sub-processors.
|
|
243
|
+
*/
|
|
244
|
+
get processors() {
|
|
245
|
+
return [];
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* The entry processors for this processor: the first processors in a
|
|
249
|
+
* compound processor. Non-compound processors return an empty list.
|
|
250
|
+
*/
|
|
251
|
+
get entryProcessors() {
|
|
252
|
+
return [];
|
|
253
|
+
}
|
|
254
|
+
/** The next processor, or null. */
|
|
255
|
+
get next() {
|
|
256
|
+
return this._next;
|
|
257
|
+
}
|
|
258
|
+
/** The previous processor, or null. */
|
|
259
|
+
get previous() {
|
|
260
|
+
return this._prev;
|
|
261
|
+
}
|
|
262
|
+
/** The configuration this processor was set up with. */
|
|
263
|
+
get processorSetup() {
|
|
264
|
+
if (!this._setup) {
|
|
265
|
+
throw new Error(`${this} is still not set up.`);
|
|
266
|
+
}
|
|
267
|
+
return this._setup;
|
|
268
|
+
}
|
|
269
|
+
/** Whether metrics collection is enabled. */
|
|
270
|
+
get metricsEnabled() {
|
|
271
|
+
return Boolean(this._setup?.enableMetrics);
|
|
272
|
+
}
|
|
273
|
+
/** Whether usage metrics collection is enabled. */
|
|
274
|
+
get usageMetricsEnabled() {
|
|
275
|
+
return Boolean(this._setup?.enableUsageMetrics);
|
|
276
|
+
}
|
|
277
|
+
/** Whether only the initial TTFB should be reported. */
|
|
278
|
+
get reportOnlyInitialTtfb() {
|
|
279
|
+
return Boolean(this._setup?.reportOnlyInitialTtfb);
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* The PipelineWorker this processor is running in. Gives access to
|
|
283
|
+
* worker-scoped state, e.g. `this.pipelineWorker.appResources`.
|
|
284
|
+
*/
|
|
285
|
+
get pipelineWorker() {
|
|
286
|
+
return this.processorSetup.pipelineWorker;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* The WorkerRunner hosting this processor's worker. Use it to reach another
|
|
290
|
+
* worker by name, e.g. `this.workerRunner.getWorker("ui-jobs")`.
|
|
291
|
+
*/
|
|
292
|
+
get workerRunner() {
|
|
293
|
+
return this.pipelineWorker.workerRunner;
|
|
294
|
+
}
|
|
295
|
+
/** Processors that can generate metrics, including nested ones. */
|
|
296
|
+
processorsWithMetrics() {
|
|
297
|
+
return [];
|
|
298
|
+
}
|
|
299
|
+
/** Whether this processor can generate metrics. */
|
|
300
|
+
canGenerateMetrics() {
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
/** Set core metrics data for this processor. */
|
|
304
|
+
setCoreMetricsData(data) {
|
|
305
|
+
this._metrics.setCoreMetricsData(data);
|
|
306
|
+
}
|
|
307
|
+
/** Start time-to-first-byte metrics collection. */
|
|
308
|
+
async startTtfbMetrics(options = {}) {
|
|
309
|
+
if (this.canGenerateMetrics() && this.metricsEnabled) {
|
|
310
|
+
await this._metrics.startTtfbMetrics({
|
|
311
|
+
startTime: options.startTime ?? null,
|
|
312
|
+
reportOnlyInitialTtfb: this.reportOnlyInitialTtfb,
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
/** Abandon the current time-to-first-byte measurement without reporting it. */
|
|
317
|
+
async cancelTtfbMetrics() {
|
|
318
|
+
if (this.canGenerateMetrics() && this.metricsEnabled) {
|
|
319
|
+
await this._metrics.cancelTtfbMetrics();
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
/** Stop time-to-first-byte metrics collection and push results. */
|
|
323
|
+
async stopTtfbMetrics(options = {}) {
|
|
324
|
+
if (this.canGenerateMetrics() && this.metricsEnabled) {
|
|
325
|
+
const frame = await this._metrics.stopTtfbMetrics({ endTime: options.endTime ?? null });
|
|
326
|
+
if (frame)
|
|
327
|
+
await this.pushFrame(frame);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Scan a TTS audio frame for the first audible sample and push TTFA.
|
|
332
|
+
* Call for every audio frame until a measurement is produced.
|
|
333
|
+
*/
|
|
334
|
+
async processTtfaMetrics(frame) {
|
|
335
|
+
if (this.canGenerateMetrics() && this.metricsEnabled) {
|
|
336
|
+
const metricsFrame = await this._metrics.processTtfaMetrics({
|
|
337
|
+
audio: frame.audio,
|
|
338
|
+
sampleRate: frame.sampleRate,
|
|
339
|
+
numChannels: frame.numChannels,
|
|
340
|
+
});
|
|
341
|
+
if (metricsFrame)
|
|
342
|
+
await this.pushFrame(metricsFrame);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
/** Stop time-to-first-answer-token metrics collection and push results. */
|
|
346
|
+
async stopTtfatMetrics(options = {}) {
|
|
347
|
+
if (this.canGenerateMetrics() && this.metricsEnabled) {
|
|
348
|
+
const frame = await this._metrics.stopTtfatMetrics({ endTime: options.endTime ?? null });
|
|
349
|
+
if (frame)
|
|
350
|
+
await this.pushFrame(frame);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
/** Start processing metrics collection. */
|
|
354
|
+
async startProcessingMetrics(options = {}) {
|
|
355
|
+
if (this.canGenerateMetrics() && this.metricsEnabled) {
|
|
356
|
+
await this._metrics.startProcessingMetrics({ startTime: options.startTime ?? null });
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
/** Stop processing metrics collection and push results. */
|
|
360
|
+
async stopProcessingMetrics(options = {}) {
|
|
361
|
+
if (this.canGenerateMetrics() && this.metricsEnabled) {
|
|
362
|
+
const frame = await this._metrics.stopProcessingMetrics({ endTime: options.endTime ?? null });
|
|
363
|
+
if (frame)
|
|
364
|
+
await this.pushFrame(frame);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
/** Start LLM usage metrics collection. */
|
|
368
|
+
async startLlmUsageMetrics(tokens) {
|
|
369
|
+
if (this.canGenerateMetrics() && this.usageMetricsEnabled) {
|
|
370
|
+
const frame = await this._metrics.startLlmUsageMetrics(tokens);
|
|
371
|
+
if (frame)
|
|
372
|
+
await this.pushFrame(frame);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
/** Start STT usage metrics collection. */
|
|
376
|
+
async startSttUsageMetrics(usage) {
|
|
377
|
+
if (this.canGenerateMetrics() && this.usageMetricsEnabled) {
|
|
378
|
+
const frame = await this._metrics.startSttUsageMetrics(usage);
|
|
379
|
+
if (frame)
|
|
380
|
+
await this.pushFrame(frame);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
/** Start TTS usage metrics collection. */
|
|
384
|
+
async startTtsUsageMetrics(text) {
|
|
385
|
+
if (this.canGenerateMetrics() && this.usageMetricsEnabled) {
|
|
386
|
+
const frame = await this._metrics.startTtsUsageMetrics(text);
|
|
387
|
+
if (frame)
|
|
388
|
+
await this.pushFrame(frame);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
/** Start text aggregation time metrics collection. */
|
|
392
|
+
async startTextAggregationMetrics() {
|
|
393
|
+
if (this.canGenerateMetrics() && this.metricsEnabled) {
|
|
394
|
+
await this._metrics.startTextAggregationMetrics();
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
/** Stop text aggregation time metrics collection and push results. */
|
|
398
|
+
async stopTextAggregationMetrics() {
|
|
399
|
+
if (this.canGenerateMetrics() && this.metricsEnabled) {
|
|
400
|
+
const frame = await this._metrics.stopTextAggregationMetrics();
|
|
401
|
+
if (frame)
|
|
402
|
+
await this.pushFrame(frame);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
/** Stop all active metrics collection. */
|
|
406
|
+
async stopAllMetrics() {
|
|
407
|
+
await this.stopTtfbMetrics();
|
|
408
|
+
await this.stopProcessingMetrics();
|
|
409
|
+
await this.stopTextAggregationMetrics();
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Set up the processor with required components.
|
|
413
|
+
*
|
|
414
|
+
* This is where a processor connects and does its other slow start-up
|
|
415
|
+
* work. A pipeline sets its processors up concurrently, so a resource
|
|
416
|
+
* shared with another processor needs guarding (see `utils/shared`).
|
|
417
|
+
*/
|
|
418
|
+
async setup(setup) {
|
|
419
|
+
await super.setup(setup.taskManager);
|
|
420
|
+
this._setup = setup;
|
|
421
|
+
if (this._metrics) {
|
|
422
|
+
await this._metrics.setup(this.taskManager);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
/** Hold the StartFrame until `_setupFinished` is called. Called by the pipeline before setup. */
|
|
426
|
+
_setupStarted() {
|
|
427
|
+
this.#setupDone.clear();
|
|
428
|
+
}
|
|
429
|
+
/** Let this processor start, once its own setup() has returned. */
|
|
430
|
+
_setupFinished() {
|
|
431
|
+
this.#setupDone.set();
|
|
432
|
+
this.#maybeCreateInputTask();
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Release this processor's resources at teardown.
|
|
436
|
+
*
|
|
437
|
+
* This base implementation cancels only the processor's internal
|
|
438
|
+
* input/process tasks; tasks created via `createTask` are released by an
|
|
439
|
+
* override. Runs concurrently with every other processor's cleanup.
|
|
440
|
+
*/
|
|
441
|
+
async cleanup() {
|
|
442
|
+
await super.cleanup();
|
|
443
|
+
await this.#cancelPauseWatcher();
|
|
444
|
+
await this.#cancelInputTask();
|
|
445
|
+
await this.#cancelProcessTask();
|
|
446
|
+
if (this._metrics) {
|
|
447
|
+
await this._metrics.cleanup();
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
/** Link this processor to the next processor in the pipeline. */
|
|
451
|
+
link(processor) {
|
|
452
|
+
this._next = processor;
|
|
453
|
+
processor._prev = this;
|
|
454
|
+
logger.debug(`Linking ${this} -> ${this._next}`);
|
|
455
|
+
}
|
|
456
|
+
/** The clock used by this processor. */
|
|
457
|
+
getClock() {
|
|
458
|
+
return this.processorSetup.clock;
|
|
459
|
+
}
|
|
460
|
+
/** The event loop used by this processor. */
|
|
461
|
+
getEventLoop() {
|
|
462
|
+
return this.taskManager.getEventLoop();
|
|
463
|
+
}
|
|
464
|
+
/** Queue a frame for processing. */
|
|
465
|
+
async queueFrame(frame, direction = FrameDirection.DOWNSTREAM, callback = null) {
|
|
466
|
+
// If we are cancelling we don't want to process any other frame.
|
|
467
|
+
if (this._cancelling)
|
|
468
|
+
return;
|
|
469
|
+
if (this._enableDirectMode) {
|
|
470
|
+
if (frame instanceof StartFrame) {
|
|
471
|
+
await this.#setupDone.wait();
|
|
472
|
+
}
|
|
473
|
+
await this.#processFrame(frame, direction, callback);
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
await this.#inputQueue.put([frame, direction, callback]);
|
|
477
|
+
// Nothing drains the queue until the StartFrame arrives and this
|
|
478
|
+
// processor is set up, so a processor never acts on a frame before it has
|
|
479
|
+
// been started. Frames pushed before that simply wait, and the StartFrame
|
|
480
|
+
// is dequeued ahead of them.
|
|
481
|
+
if (frame instanceof StartFrame) {
|
|
482
|
+
this.#startReceived = true;
|
|
483
|
+
this.#maybeCreateInputTask();
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
/** Pause processing of queued frames. */
|
|
487
|
+
async pauseProcessingFrames() {
|
|
488
|
+
logger.trace(`${this}: pausing frame processing`);
|
|
489
|
+
this.#shouldBlockFrames = true;
|
|
490
|
+
this.#processEvent?.clear();
|
|
491
|
+
}
|
|
492
|
+
/** Pause processing of queued system frames. */
|
|
493
|
+
async pauseProcessingSystemFrames() {
|
|
494
|
+
logger.trace(`${this}: pausing system frame processing`);
|
|
495
|
+
this.#shouldBlockSystemFrames = true;
|
|
496
|
+
this.#inputEvent?.clear();
|
|
497
|
+
}
|
|
498
|
+
/** Resume processing of queued frames. */
|
|
499
|
+
async resumeProcessingFrames() {
|
|
500
|
+
logger.trace(`${this}: resuming frame processing`);
|
|
501
|
+
this.#processEvent?.set();
|
|
502
|
+
}
|
|
503
|
+
/** Resume processing of queued system frames. */
|
|
504
|
+
async resumeProcessingSystemFrames() {
|
|
505
|
+
logger.trace(`${this}: resuming system frame processing`);
|
|
506
|
+
this.#inputEvent?.set();
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Hold frames arriving at this processor until `ready` resolves.
|
|
510
|
+
*
|
|
511
|
+
* Useful for a processor that cannot act on frames until some condition
|
|
512
|
+
* holds, such as one that establishes a connection in the background.
|
|
513
|
+
* Frames wait in the processor's queues and are delivered in order once
|
|
514
|
+
* the condition resolves, so nothing is lost.
|
|
515
|
+
*
|
|
516
|
+
* The frame being processed when this is called is unaffected: the pause
|
|
517
|
+
* takes hold from the next frame onwards.
|
|
518
|
+
*
|
|
519
|
+
* Both queues are held, so the pause is always lifted: when `ready`
|
|
520
|
+
* resolves, when `timeout` (seconds) elapses, or at teardown.
|
|
521
|
+
*
|
|
522
|
+
* @param ready Awaited to learn when frames can be acted on, e.g. `() => someEvent.wait()`.
|
|
523
|
+
*/
|
|
524
|
+
async pauseProcessingAllFramesUntil(ready, options = {}) {
|
|
525
|
+
const timeout = options.timeout ?? PAUSE_UNTIL_READY_TIMEOUT_SECS;
|
|
526
|
+
if (this._enableDirectMode) {
|
|
527
|
+
logger.warning(`${this}: cannot hold frames, this processor runs in direct mode`);
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
await this.#cancelPauseWatcher();
|
|
531
|
+
await this.pauseProcessingSystemFrames();
|
|
532
|
+
await this.pauseProcessingFrames();
|
|
533
|
+
this.#pauseWatcherTask = this.createTask(() => this.#pauseWatcherHandler(ready, timeout), `${this}::pause_watcher`);
|
|
534
|
+
}
|
|
535
|
+
/** Lift the pause taken by pauseProcessingAllFramesUntil(). */
|
|
536
|
+
async #pauseWatcherHandler(ready, timeout) {
|
|
537
|
+
try {
|
|
538
|
+
await waitFor(ready, timeout);
|
|
539
|
+
}
|
|
540
|
+
catch (e) {
|
|
541
|
+
if (!(e instanceof TimeoutError))
|
|
542
|
+
throw e;
|
|
543
|
+
logger.warning(`${this}: still not ready after ${timeout}s, resuming frame processing anyway`);
|
|
544
|
+
}
|
|
545
|
+
await this.#resumeProcessingAllFrames();
|
|
546
|
+
}
|
|
547
|
+
/** Stop watching, and lift the pause the watcher was going to lift. */
|
|
548
|
+
async #cancelPauseWatcher() {
|
|
549
|
+
if (!this.#pauseWatcherTask)
|
|
550
|
+
return;
|
|
551
|
+
const task = this.#pauseWatcherTask;
|
|
552
|
+
this.#pauseWatcherTask = null;
|
|
553
|
+
await this.cancelTask(task);
|
|
554
|
+
await this.#resumeProcessingAllFrames();
|
|
555
|
+
}
|
|
556
|
+
/** Resume both queues held by pauseProcessingAllFramesUntil(). */
|
|
557
|
+
async #resumeProcessingAllFrames() {
|
|
558
|
+
await this.resumeProcessingSystemFrames();
|
|
559
|
+
await this.resumeProcessingFrames();
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* Process a frame. Subclasses override this and call
|
|
563
|
+
* `await super.processFrame(frame, direction)` first.
|
|
564
|
+
*/
|
|
565
|
+
async processFrame(frame, direction) {
|
|
566
|
+
const observer = this._setup?.observer;
|
|
567
|
+
if (observer) {
|
|
568
|
+
const data = new FrameProcessed({
|
|
569
|
+
processor: this,
|
|
570
|
+
frame,
|
|
571
|
+
direction,
|
|
572
|
+
timestamp: this.getClock().getTime(),
|
|
573
|
+
});
|
|
574
|
+
await observer.onProcessFrame(data);
|
|
575
|
+
}
|
|
576
|
+
if (frame instanceof StartFrame) {
|
|
577
|
+
await this.#start(frame);
|
|
578
|
+
}
|
|
579
|
+
else if (frame instanceof InterruptionFrame) {
|
|
580
|
+
await this._startInterruption();
|
|
581
|
+
await this.stopAllMetrics();
|
|
582
|
+
}
|
|
583
|
+
else if (frame instanceof CancelFrame) {
|
|
584
|
+
await this.#cancel(frame);
|
|
585
|
+
}
|
|
586
|
+
else if (frame instanceof FrameProcessorPauseFrame ||
|
|
587
|
+
frame instanceof FrameProcessorPauseUrgentFrame) {
|
|
588
|
+
await this.#pause(frame);
|
|
589
|
+
}
|
|
590
|
+
else if (frame instanceof FrameProcessorResumeFrame ||
|
|
591
|
+
frame instanceof FrameProcessorResumeUrgentFrame) {
|
|
592
|
+
await this.#resume(frame);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
* Classify an exception this processor knows the shape of. Override for
|
|
597
|
+
* providers that signal failures through SDK-specific errors rather than an
|
|
598
|
+
* HTTP status code. Return null to fall back to `classifyHttpException`.
|
|
599
|
+
*/
|
|
600
|
+
_classifyError(_exception) {
|
|
601
|
+
return null;
|
|
602
|
+
}
|
|
603
|
+
/**
|
|
604
|
+
* Create and push an ErrorFrame upstream, with context about which
|
|
605
|
+
* processor generated the error.
|
|
606
|
+
*
|
|
607
|
+
* @param errorMsg Descriptive message explaining the error condition.
|
|
608
|
+
* @param options.exception The error that caused it, if available.
|
|
609
|
+
* @param options.category Why the error occurred, when the caller knows.
|
|
610
|
+
* Leave unset to work it out from the exception, or pass
|
|
611
|
+
* `ErrorCategory.UNKNOWN` for an error whose cause can't be attributed.
|
|
612
|
+
* @param options.forceTreatAsPermanent Treat this error as one that will
|
|
613
|
+
* keep recurring, leaving the processor unable to do any more work. The
|
|
614
|
+
* pipeline worker then applies its ProcessorUnusablePolicy.
|
|
615
|
+
*
|
|
616
|
+
* @example
|
|
617
|
+
* // An error this processor can recover from
|
|
618
|
+
* await this.pushError("Failed to process audio chunk, skipping");
|
|
619
|
+
*
|
|
620
|
+
* // An error that leaves this processor unable to do any more work
|
|
621
|
+
* try {
|
|
622
|
+
* someCriticalOperation();
|
|
623
|
+
* } catch (e) {
|
|
624
|
+
* await this.pushError("Critical operation failed", { exception: e, forceTreatAsPermanent: true });
|
|
625
|
+
* }
|
|
626
|
+
*/
|
|
627
|
+
async pushError(errorMsg, options = {}) {
|
|
628
|
+
const errorFrame = new ErrorFrame({
|
|
629
|
+
error: errorMsg,
|
|
630
|
+
exception: options.exception ?? null,
|
|
631
|
+
processor: this,
|
|
632
|
+
category: options.category ?? null,
|
|
633
|
+
});
|
|
634
|
+
await this.pushErrorFrame(errorFrame, {
|
|
635
|
+
forceTreatAsPermanent: options.forceTreatAsPermanent ?? false,
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* Push an error frame upstream.
|
|
640
|
+
*
|
|
641
|
+
* @param options.forceTreatAsPermanent See `pushError`.
|
|
642
|
+
*/
|
|
643
|
+
async pushErrorFrame(error, options = {}) {
|
|
644
|
+
if (!error.processor) {
|
|
645
|
+
error.processor = this;
|
|
646
|
+
}
|
|
647
|
+
// Anything still unset by now is going to stay that way, so settle it here
|
|
648
|
+
// and let handlers read a category off every error they receive.
|
|
649
|
+
if (error.category === null && error.exception) {
|
|
650
|
+
error.category =
|
|
651
|
+
this._classifyError(error.exception) ?? classifyHttpException(error.exception);
|
|
652
|
+
}
|
|
653
|
+
if (error.category === null) {
|
|
654
|
+
error.category = ErrorCategory.UNKNOWN;
|
|
655
|
+
}
|
|
656
|
+
// Before anything sees the error, so that handlers reading
|
|
657
|
+
// `frame.processor.isUsable` get the verdict that came with it.
|
|
658
|
+
if (options.forceTreatAsPermanent || error.category.isPermanent) {
|
|
659
|
+
await this.setUsable(false);
|
|
660
|
+
}
|
|
661
|
+
await this._callEventHandler("on_error", error);
|
|
662
|
+
if (error.exception) {
|
|
663
|
+
logger.error(`${error.processor} exception: ${error.error}`, error.exception);
|
|
664
|
+
}
|
|
665
|
+
else {
|
|
666
|
+
logger.error(`${error.processor} error: ${error.error}`);
|
|
667
|
+
}
|
|
668
|
+
await this.pushFrame(error, FrameDirection.UPSTREAM);
|
|
669
|
+
}
|
|
670
|
+
/** Push a frame to the next (downstream) or previous (upstream) processor. */
|
|
671
|
+
async pushFrame(frame, direction = FrameDirection.DOWNSTREAM) {
|
|
672
|
+
await this._callEventHandler("on_before_push_frame", frame);
|
|
673
|
+
await this.#internalPushFrame(frame, direction);
|
|
674
|
+
await this._callEventHandler("on_after_push_frame", frame);
|
|
675
|
+
}
|
|
676
|
+
/** Broadcast an InterruptionFrame both upstream and downstream. */
|
|
677
|
+
async broadcastInterruption() {
|
|
678
|
+
logger.debug(`${this}: broadcasting interruption`);
|
|
679
|
+
this.#resetProcessTask();
|
|
680
|
+
await this.stopAllMetrics();
|
|
681
|
+
await this.broadcastFrame(InterruptionFrame);
|
|
682
|
+
}
|
|
683
|
+
/**
|
|
684
|
+
* Broadcast a frame of the specified class upstream and downstream.
|
|
685
|
+
*
|
|
686
|
+
* Creates two instances of the given frame class from the provided options
|
|
687
|
+
* (without deep-copying them) and pushes them upstream and downstream.
|
|
688
|
+
*/
|
|
689
|
+
async broadcastFrame(frameCls, options) {
|
|
690
|
+
const downstreamFrame = new frameCls(options);
|
|
691
|
+
const upstreamFrame = new frameCls(options);
|
|
692
|
+
downstreamFrame.broadcastSiblingId = upstreamFrame.id;
|
|
693
|
+
upstreamFrame.broadcastSiblingId = downstreamFrame.id;
|
|
694
|
+
await this.pushFrame(downstreamFrame);
|
|
695
|
+
await this.pushFrame(upstreamFrame, FrameDirection.UPSTREAM);
|
|
696
|
+
}
|
|
697
|
+
/**
|
|
698
|
+
* Broadcast a frame instance upstream and downstream.
|
|
699
|
+
*
|
|
700
|
+
* Creates two new frames shallow-copying all fields from the original
|
|
701
|
+
* frame except `id` and `name`, which get fresh values. Prefer
|
|
702
|
+
* `broadcastFrame()` when you are the creator of the frame.
|
|
703
|
+
*/
|
|
704
|
+
async broadcastFrameInstance(frame) {
|
|
705
|
+
const copy = () => {
|
|
706
|
+
const clone = Object.assign(Object.create(Object.getPrototypeOf(frame)), frame);
|
|
707
|
+
renewFrameIdentity(clone);
|
|
708
|
+
return clone;
|
|
709
|
+
};
|
|
710
|
+
const downstreamFrame = copy();
|
|
711
|
+
const upstreamFrame = copy();
|
|
712
|
+
downstreamFrame.broadcastSiblingId = upstreamFrame.id;
|
|
713
|
+
upstreamFrame.broadcastSiblingId = downstreamFrame.id;
|
|
714
|
+
await this.pushFrame(downstreamFrame);
|
|
715
|
+
await this.pushFrame(upstreamFrame, FrameDirection.UPSTREAM);
|
|
716
|
+
}
|
|
717
|
+
async #start(_frame) {
|
|
718
|
+
this.#createProcessTask();
|
|
719
|
+
}
|
|
720
|
+
async #cancel(_frame) {
|
|
721
|
+
this._cancelling = true;
|
|
722
|
+
await this.#cancelProcessTask();
|
|
723
|
+
}
|
|
724
|
+
async #pause(frame) {
|
|
725
|
+
if (frame.processor.name === this.name) {
|
|
726
|
+
await this.pauseProcessingFrames();
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
async #resume(frame) {
|
|
730
|
+
if (frame.processor.name === this.name) {
|
|
731
|
+
await this.resumeProcessingFrames();
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
//
|
|
735
|
+
// Handle interruptions
|
|
736
|
+
//
|
|
737
|
+
/** Start handling an interruption by cancelling current tasks. */
|
|
738
|
+
async _startInterruption() {
|
|
739
|
+
try {
|
|
740
|
+
const current = this.#processCurrentFrame;
|
|
741
|
+
const currentIsUninterruptible = current !== null && !current.interruptible;
|
|
742
|
+
if (currentIsUninterruptible) {
|
|
743
|
+
// The frame currently being processed is uninterruptible, so we must
|
|
744
|
+
// not cancel it. Just flush interruptible frames from the queue; any
|
|
745
|
+
// uninterruptible ones will be kept and processed after the current
|
|
746
|
+
// frame finishes.
|
|
747
|
+
this.#resetProcessQueue();
|
|
748
|
+
}
|
|
749
|
+
else {
|
|
750
|
+
// Cancel and re-create the process task. Uninterruptible queued frames
|
|
751
|
+
// are safe here because #createProcessTask resets the process queue,
|
|
752
|
+
// which always preserves them.
|
|
753
|
+
await this.#cancelProcessTask();
|
|
754
|
+
this.#createProcessTask();
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
catch (e) {
|
|
758
|
+
rethrowIfCancelled(e);
|
|
759
|
+
await this.pushError(`Uncaught exception handling _start_interruption: ${errorMessage(e)}`, {
|
|
760
|
+
exception: e,
|
|
761
|
+
// A broad catch: this may not have come from this processor at all,
|
|
762
|
+
// so its cause can't be attributed.
|
|
763
|
+
category: ErrorCategory.UNKNOWN,
|
|
764
|
+
});
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
async #internalPushFrame(frame, direction) {
|
|
768
|
+
const observer = this._setup?.observer;
|
|
769
|
+
try {
|
|
770
|
+
const timestamp = this._setup ? this.getClock().getTime() : 0;
|
|
771
|
+
if (direction === FrameDirection.DOWNSTREAM && this._next) {
|
|
772
|
+
logger.trace(`Pushing ${frame} downstream from ${this} to ${this._next}`);
|
|
773
|
+
if (observer) {
|
|
774
|
+
const data = new FramePushed({
|
|
775
|
+
source: this,
|
|
776
|
+
destination: this._next,
|
|
777
|
+
frame,
|
|
778
|
+
direction,
|
|
779
|
+
timestamp,
|
|
780
|
+
});
|
|
781
|
+
await observer.onPushFrame(data);
|
|
782
|
+
}
|
|
783
|
+
await this._next.queueFrame(frame, direction);
|
|
784
|
+
}
|
|
785
|
+
else if (direction === FrameDirection.UPSTREAM && this._prev) {
|
|
786
|
+
logger.trace(`Pushing ${frame} upstream from ${this} to ${this._prev}`);
|
|
787
|
+
if (observer) {
|
|
788
|
+
const data = new FramePushed({
|
|
789
|
+
source: this,
|
|
790
|
+
destination: this._prev,
|
|
791
|
+
frame,
|
|
792
|
+
direction,
|
|
793
|
+
timestamp,
|
|
794
|
+
});
|
|
795
|
+
await observer.onPushFrame(data);
|
|
796
|
+
}
|
|
797
|
+
await this._prev.queueFrame(frame, direction);
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
catch (e) {
|
|
801
|
+
rethrowIfCancelled(e);
|
|
802
|
+
// Observers and the downstream processor run inside this block, so the
|
|
803
|
+
// cause of an unexpected failure can't be attributed.
|
|
804
|
+
await this.pushError(`Uncaught exception: ${errorMessage(e)}`, {
|
|
805
|
+
exception: e,
|
|
806
|
+
category: ErrorCategory.UNKNOWN,
|
|
807
|
+
});
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
/** Create the input task once the StartFrame is here and setup is done. */
|
|
811
|
+
#maybeCreateInputTask() {
|
|
812
|
+
if (!this.#startReceived || !this.#setupDone.isSet())
|
|
813
|
+
return;
|
|
814
|
+
if (!this._taskManager) {
|
|
815
|
+
// Setting up was cut short before FrameProcessor.setup() ran, so there
|
|
816
|
+
// is no task manager to start processing frames with.
|
|
817
|
+
logger.error(`${this}: can't start, setup ended before FrameProcessor.setup() was ` +
|
|
818
|
+
"called (call super.setup() before anything that can block)");
|
|
819
|
+
return;
|
|
820
|
+
}
|
|
821
|
+
this.#createInputTask();
|
|
822
|
+
}
|
|
823
|
+
#createInputTask() {
|
|
824
|
+
if (this._enableDirectMode)
|
|
825
|
+
return;
|
|
826
|
+
if (!this.#inputFrameTask) {
|
|
827
|
+
this.#inputEvent = new Event();
|
|
828
|
+
this.#inputFrameTask = this.createTask(() => this.#inputFrameTaskHandler(), "__input_frame_task_handler");
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
async #cancelInputTask() {
|
|
832
|
+
if (this.#inputFrameTask) {
|
|
833
|
+
// Apply a timeout as a safeguard: if some code swallows cancellation,
|
|
834
|
+
// the task would otherwise never be cancelled.
|
|
835
|
+
await this.cancelTask(this.#inputFrameTask, INPUT_TASK_CANCEL_TIMEOUT_SECS);
|
|
836
|
+
this.#inputFrameTask = null;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
#createProcessTask() {
|
|
840
|
+
if (this._enableDirectMode)
|
|
841
|
+
return;
|
|
842
|
+
if (!this.#processFrameTask) {
|
|
843
|
+
this.#resetProcessTask();
|
|
844
|
+
this.#processFrameTask = this.createTask(() => this.#processFrameTaskHandler(), "__process_frame_task_handler");
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
#resetProcessTask() {
|
|
848
|
+
if (this._enableDirectMode)
|
|
849
|
+
return;
|
|
850
|
+
this.#shouldBlockFrames = false;
|
|
851
|
+
this.#processEvent = new Event();
|
|
852
|
+
this.#resetProcessQueue();
|
|
853
|
+
}
|
|
854
|
+
#resetProcessQueue() {
|
|
855
|
+
this.#processQueue.reset();
|
|
856
|
+
}
|
|
857
|
+
/** Whether a frame of the given type is waiting in the processing queue. */
|
|
858
|
+
hasQueuedFrame(frameType) {
|
|
859
|
+
return this.#processQueue.hasFrame(frameType);
|
|
860
|
+
}
|
|
861
|
+
async #cancelProcessTask() {
|
|
862
|
+
if (this.#processFrameTask) {
|
|
863
|
+
await this.cancelTask(this.#processFrameTask);
|
|
864
|
+
this.#processFrameTask = null;
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
async #processFrame(frame, direction, callback) {
|
|
868
|
+
try {
|
|
869
|
+
await this._callEventHandler("on_before_process_frame", frame);
|
|
870
|
+
// Process the frame.
|
|
871
|
+
await this.processFrame(frame, direction);
|
|
872
|
+
// If this frame has an associated callback, call it now.
|
|
873
|
+
if (callback) {
|
|
874
|
+
await callback(this, frame, direction);
|
|
875
|
+
}
|
|
876
|
+
await this._callEventHandler("on_after_process_frame", frame);
|
|
877
|
+
}
|
|
878
|
+
catch (e) {
|
|
879
|
+
rethrowIfCancelled(e);
|
|
880
|
+
// The frame callback runs inside this block, so the cause of an
|
|
881
|
+
// unexpected failure can't be attributed.
|
|
882
|
+
await this.pushError(`Error processing frame: ${errorMessage(e)}`, {
|
|
883
|
+
exception: e,
|
|
884
|
+
category: ErrorCategory.UNKNOWN,
|
|
885
|
+
});
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
/**
|
|
889
|
+
* Handle frames from the input queue. Only processes system frames; other
|
|
890
|
+
* frames are queued for the process task.
|
|
891
|
+
*/
|
|
892
|
+
async #inputFrameTaskHandler() {
|
|
893
|
+
for (;;) {
|
|
894
|
+
const [frame, direction, callback] = await this.#inputQueue.get();
|
|
895
|
+
if (this.#shouldBlockSystemFrames && this.#inputEvent) {
|
|
896
|
+
logger.trace(`${this}: system frame processing paused`);
|
|
897
|
+
await this.#inputEvent.wait();
|
|
898
|
+
this.#inputEvent.clear();
|
|
899
|
+
this.#shouldBlockSystemFrames = false;
|
|
900
|
+
logger.trace(`${this}: system frame processing resumed`);
|
|
901
|
+
}
|
|
902
|
+
if (frame instanceof SystemFrame) {
|
|
903
|
+
await this.#processFrame(frame, direction, callback);
|
|
904
|
+
}
|
|
905
|
+
else {
|
|
906
|
+
await this.#processQueue.put([frame, direction, callback]);
|
|
907
|
+
}
|
|
908
|
+
this.#inputQueue.taskDone();
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
/** Handle non-system frames from the process queue. */
|
|
912
|
+
async #processFrameTaskHandler() {
|
|
913
|
+
for (;;) {
|
|
914
|
+
this.#processCurrentFrame = null;
|
|
915
|
+
const [frame, direction, callback] = await this.#processQueue.get();
|
|
916
|
+
this.#processCurrentFrame = frame;
|
|
917
|
+
if (this.#shouldBlockFrames && this.#processEvent) {
|
|
918
|
+
logger.trace(`${this}: frame processing paused`);
|
|
919
|
+
await this.#processEvent.wait();
|
|
920
|
+
this.#processEvent.clear();
|
|
921
|
+
this.#shouldBlockFrames = false;
|
|
922
|
+
logger.trace(`${this}: frame processing resumed`);
|
|
923
|
+
}
|
|
924
|
+
await this.#processFrame(frame, direction, callback);
|
|
925
|
+
this.#processQueue.taskDone();
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
function errorMessage(e) {
|
|
930
|
+
return e instanceof Error ? e.message : String(e);
|
|
931
|
+
}
|
|
932
|
+
//# sourceMappingURL=frame_processor.js.map
|