From b03247f3606b9947ad1a5b36e9083ab35cb168eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleix=20Conchillo=20Flaqu=C3=A9?= Date: Wed, 20 May 2026 16:39:45 -0700 Subject: [PATCH] =?UTF-8?q?Rename=20BaseTask=20=E2=86=92=20BaseWorker=20an?= =?UTF-8?q?d=20reserve=20"task"=20for=20asyncio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces every "task" identifier that referred to the BaseTask abstraction with "worker". Asyncio task plumbing (asyncio.Task, BaseTaskManager, TaskManager, create_task, cancel_task, etc.) stays untouched. Highlights: - Classes: BaseTask → BaseWorker, PipelineTask → PipelineWorker, LLMTask → LLMWorker, LLMContextTask → LLMContextWorker, TaskBus → WorkerBus, TaskRegistry → WorkerRegistry, TaskActivationArgs → WorkerActivationArgs, TaskReadyData → WorkerReadyData, TaskRegistryEntry → WorkerRegistryEntry, TaskObserver → WorkerObserver, all Bus*TaskMessage → Bus*WorkerMessage, BusAddTaskMessage.task field → worker, BusWorkerRegistryMessage.tasks field → workers. - Methods/decorators: activate_task → activate_worker, deactivate_task → deactivate_worker, add_task → add_worker, watch_task → watch_worker, @task_ready → @worker_ready, setup_pipeline_task hook → setup_pipeline_worker. - Params/fields: FrameProcessorSetup.pipeline_task and FunctionCallParams.pipeline_task → pipeline_worker. Parameter names like task_name → worker_name; spawn/run accept worker:. - Files: pipeline/base_task.py → base_worker.py, pipeline/task.py → worker.py (plus a re-export shim at pipeline/task.py), task_observer.py → worker_observer.py, task_ready_decorator.py → worker_ready_decorator.py, pipecat.tasks → pipecat.workers, llm_task.py → llm_worker.py, llm_context_task.py → llm_context_worker.py, examples/multi-task → examples/multi-worker. Back-compat: - PipelineTask kept as a deprecated subclass of PipelineWorker that warns on construction. - pipecat.pipeline.task re-exports PipelineWorker/PipelineTask/etc. so existing user imports keep working. - FrameProcessor.pipeline_task kept as a deprecated property that forwards to pipeline_worker. Local variables in examples that hold a worker (task = PipelineTask(...)) are renamed to worker = PipelineWorker(...). Asyncio-task locals (runner_task, etc.) are preserved. --- changelog/4493.added.md | 2 +- changelog/4493.changed.2.md | 2 +- changelog/4493.changed.md | 2 +- examples/audio/audio-bot-background-sound.py | 16 +- examples/audio/audio-recording.py | 10 +- examples/audio/audio-sound-effects.py | 10 +- .../context-summarization-dedicated-llm.py | 10 +- .../context-summarization-google.py | 10 +- .../context-summarization-manual-openai.py | 10 +- .../context-summarization-openai.py | 10 +- .../features-add-tool-change-messages.py | 14 +- examples/features/features-app-resources.py | 30 +- .../features-before-and-after-events.py | 12 +- .../features-concurrent-llm-evaluation.py | 10 +- ...res-concurrent-llm-rtvi-ignored-sources.py | 10 +- .../features-custom-frame-processor.py | 10 +- .../features-gpu-container-local-bot.py | 14 +- .../features/features-live-translation.py | 10 +- .../features-pattern-pair-voice-switching.py | 10 +- .../features/features-service-switcher.py | 16 +- .../features/features-switch-languages.py | 10 +- examples/features/features-switch-voices.py | 10 +- .../features/features-user-email-gathering.py | 10 +- .../features/features-voicemail-detection.py | 8 +- examples/features/features-wake-phrase.py | 10 +- ...function-calling-anthropic-async-stream.py | 10 +- .../function-calling-anthropic-async.py | 10 +- .../function-calling-anthropic-video.py | 10 +- .../function-calling-anthropic.py | 10 +- .../function-calling-aws-video.py | 10 +- .../function-calling/function-calling-aws.py | 10 +- .../function-calling-azure.py | 10 +- .../function-calling-cerebras.py | 10 +- .../function-calling-deepseek.py | 10 +- .../function-calling-direct.py | 10 +- .../function-calling-fireworks.py | 10 +- .../function-calling-google-async-stream.py | 10 +- .../function-calling-google-async.py | 10 +- .../function-calling-google-vertex.py | 10 +- .../function-calling-google-video.py | 10 +- .../function-calling-google.py | 10 +- .../function-calling/function-calling-grok.py | 10 +- .../function-calling/function-calling-groq.py | 10 +- .../function-calling-missing-handler.py | 10 +- .../function-calling-mistral.py | 10 +- .../function-calling-moondream-video.py | 10 +- .../function-calling-nebius.py | 10 +- .../function-calling-novita.py | 10 +- .../function-calling-nvidia.py | 10 +- .../function-calling-ollama.py | 10 +- .../function-calling-openai-async-stream.py | 10 +- .../function-calling-openai-async.py | 10 +- ...n-calling-openai-responses-async-stream.py | 10 +- ...function-calling-openai-responses-async.py | 10 +- .../function-calling-openai-responses-http.py | 10 +- ...ion-calling-openai-responses-video-http.py | 10 +- ...function-calling-openai-responses-video.py | 10 +- .../function-calling-openai-responses.py | 10 +- .../function-calling-openai-video.py | 10 +- .../function-calling-openai.py | 10 +- .../function-calling-openrouter.py | 10 +- .../function-calling-perplexity.py | 10 +- .../function-calling/function-calling-qwen.py | 10 +- .../function-calling-sambanova.py | 10 +- .../function-calling-sarvam.py | 10 +- .../function-calling-together.py | 10 +- examples/getting-started/01-say-one-thing.py | 8 +- examples/getting-started/01a-local-audio.py | 8 +- .../getting-started/02-llm-say-one-thing.py | 8 +- examples/getting-started/03-still-frame.py | 14 +- .../getting-started/03a-local-still-frame.py | 10 +- .../04-sync-speech-and-image.py | 10 +- examples/getting-started/05-speaking-state.py | 10 +- examples/getting-started/06-voice-agent.py | 10 +- .../getting-started/06a-voice-agent-local.py | 8 +- .../getting-started/07-function-calling.py | 10 +- examples/mcp/mcp-multiple-mcp.py | 10 +- examples/mcp/mcp-stdio.py | 10 +- .../mcp/mcp-streamable-http-gemini-live.py | 10 +- examples/mcp/mcp-streamable-http.py | 10 +- .../{multi-task => multi-worker}/README.md | 78 +- .../code-assistant/code-assistant.py | 14 +- .../code-assistant/code_worker.py | 12 +- .../distributed-handoff/pgmq-handoff/llm.py | 28 +- .../distributed-handoff/pgmq-handoff/main.py | 26 +- .../distributed-handoff/redis-handoff/llm.py | 28 +- .../distributed-handoff/redis-handoff/main.py | 28 +- .../{multi-task => multi-worker}/env.example | 0 .../local-handoff-two-agents-tts.py | 48 +- .../local-handoff/local-handoff-two-agents.py | 46 +- .../parallel-debate/parallel-debate.py | 26 +- .../remote-proxy-assistant/assistant.py | 18 +- .../remote-proxy-assistant/main.py | 32 +- .../sensor-controller/sensor-controller.py | 24 +- .../sensor-controller/sensor.py | 0 .../observability/observability-heartbeats.py | 6 +- .../observability/observability-observer.py | 10 +- .../observability-sentry-metrics.py | 10 +- .../persistent-context-anthropic.py | 10 +- .../persistent-context-aws-nova-sonic.py | 10 +- .../persistent-context-gemini.py | 10 +- .../persistent-context-grok-realtime.py | 10 +- .../persistent-context-openai-realtime.py | 10 +- ...ersistent-context-openai-responses-http.py | 10 +- .../persistent-context-openai-responses.py | 10 +- .../persistent-context-openai.py | 10 +- examples/rag/rag-gemini-grounding-metadata.py | 10 +- examples/rag/rag-gemini.py | 10 +- examples/rag/rag-mem0.py | 10 +- .../realtime-aws-nova-sonic-async-tool.py | 10 +- examples/realtime/realtime-aws-nova-sonic.py | 12 +- .../realtime/realtime-azure-async-tool.py | 10 +- examples/realtime/realtime-azure.py | 10 +- .../realtime-gemini-live-async-tool.py | 10 +- .../realtime-gemini-live-files-api.py | 12 +- .../realtime-gemini-live-google-search.py | 10 +- .../realtime-gemini-live-graceful-end.py | 10 +- ...realtime-gemini-live-grounding-metadata.py | 10 +- .../realtime-gemini-live-local-vad.py | 10 +- .../realtime/realtime-gemini-live-vertex.py | 10 +- .../realtime/realtime-gemini-live-video.py | 10 +- examples/realtime/realtime-gemini-live.py | 10 +- examples/realtime/realtime-grok-async-tool.py | 10 +- examples/realtime/realtime-grok.py | 10 +- examples/realtime/realtime-inworld.py | 10 +- .../realtime/realtime-openai-async-tool.py | 10 +- .../realtime/realtime-openai-live-video.py | 10 +- examples/realtime/realtime-openai-text.py | 10 +- examples/realtime/realtime-openai.py | 16 +- .../realtime/realtime-ultravox-async-tool.py | 8 +- examples/realtime/realtime-ultravox-text.py | 10 +- examples/realtime/realtime-ultravox.py | 10 +- examples/thinking/thinking-anthropic.py | 10 +- .../thinking/thinking-functions-anthropic.py | 10 +- .../thinking/thinking-functions-google.py | 10 +- examples/thinking/thinking-google.py | 10 +- .../transcription/transcription-assemblyai.py | 8 +- examples/transcription/transcription-azure.py | 8 +- .../transcription/transcription-cartesia.py | 8 +- .../transcription/transcription-deepgram.py | 8 +- .../transcription/transcription-elevenlabs.py | 8 +- .../transcription-gladia-translation.py | 8 +- .../transcription/transcription-gladia.py | 8 +- .../transcription/transcription-google-llm.py | 10 +- .../transcription/transcription-gradium.py | 8 +- .../transcription/transcription-mistral.py | 8 +- .../transcription/transcription-openai.py | 8 +- .../transcription/transcription-soniox.py | 8 +- .../transcription-speechmatics.py | 8 +- .../transcription-whisper-local.py | 6 +- .../transcription-whisper-mlx.py | 8 +- .../transcription/transcription-whisper.py | 8 +- examples/transcription/transcription-xai.py | 8 +- examples/transports/transports-daily.py | 10 +- examples/transports/transports-livekit.py | 10 +- .../transports/transports-small-webrtc.py | 12 +- examples/transports/transports-vonage.py | 8 +- .../turn-management-detect-user-idle.py | 14 +- ...ilter-incomplete-turns-function-calling.py | 10 +- ...turn-management-filter-incomplete-turns.py | 10 +- .../turn-management-interruption-config.py | 10 +- ...turn-management-smart-turn-local-coreml.py | 10 +- .../turn-management-smart-turn-local.py | 10 +- .../turn-management-turn-tracking-observer.py | 12 +- .../turn-management-user-assistant-turns.py | 10 +- .../turn-management-user-mute-strategy.py | 10 +- examples/update-settings/llm/llm-anthropic.py | 12 +- .../update-settings/llm/llm-aws-bedrock.py | 12 +- .../update-settings/llm/llm-aws-nova-sonic.py | 12 +- .../update-settings/llm/llm-azure-realtime.py | 14 +- examples/update-settings/llm/llm-azure.py | 12 +- examples/update-settings/llm/llm-cerebras.py | 12 +- examples/update-settings/llm/llm-deepseek.py | 12 +- examples/update-settings/llm/llm-fireworks.py | 12 +- .../llm/llm-gemini-live-vertex.py | 12 +- .../update-settings/llm/llm-gemini-live.py | 12 +- .../update-settings/llm/llm-google-vertex.py | 12 +- examples/update-settings/llm/llm-google.py | 12 +- .../update-settings/llm/llm-grok-realtime.py | 12 +- examples/update-settings/llm/llm-grok.py | 12 +- examples/update-settings/llm/llm-groq.py | 12 +- examples/update-settings/llm/llm-mistral.py | 12 +- examples/update-settings/llm/llm-nvidia.py | 12 +- examples/update-settings/llm/llm-ollama.py | 12 +- .../llm/llm-openai-realtime.py | 14 +- .../llm/llm-openai-responses-http.py | 12 +- .../llm/llm-openai-responses.py | 12 +- examples/update-settings/llm/llm-openai.py | 12 +- .../update-settings/llm/llm-openrouter.py | 12 +- .../update-settings/llm/llm-perplexity.py | 12 +- examples/update-settings/llm/llm-qwen.py | 12 +- examples/update-settings/llm/llm-sambanova.py | 12 +- examples/update-settings/llm/llm-sarvam.py | 12 +- examples/update-settings/llm/llm-together.py | 12 +- .../llm/llm-ultravox-realtime.py | 14 +- .../update-settings/stt/stt-assemblyai.py | 12 +- .../update-settings/stt/stt-aws-transcribe.py | 12 +- examples/update-settings/stt/stt-azure.py | 12 +- examples/update-settings/stt/stt-cartesia.py | 12 +- .../update-settings/stt/stt-deepgram-flux.py | 14 +- .../stt/stt-deepgram-sagemaker.py | 14 +- examples/update-settings/stt/stt-deepgram.py | 14 +- .../stt/stt-elevenlabs-realtime.py | 12 +- .../update-settings/stt/stt-elevenlabs.py | 12 +- examples/update-settings/stt/stt-fal.py | 16 +- examples/update-settings/stt/stt-gladia.py | 12 +- examples/update-settings/stt/stt-google.py | 12 +- examples/update-settings/stt/stt-gradium.py | 12 +- examples/update-settings/stt/stt-groq.py | 14 +- .../stt/stt-nvidia-segmented.py | 12 +- examples/update-settings/stt/stt-nvidia.py | 12 +- .../stt/stt-openai-realtime.py | 12 +- examples/update-settings/stt/stt-sarvam.py | 12 +- examples/update-settings/stt/stt-soniox.py | 12 +- .../update-settings/stt/stt-speechmatics.py | 16 +- .../update-settings/stt/stt-whisper-api.py | 14 +- .../update-settings/stt/stt-whisper-mlx.py | 12 +- examples/update-settings/stt/stt-whisper.py | 12 +- .../update-settings/tts/tts-asyncai-http.py | 12 +- examples/update-settings/tts/tts-asyncai.py | 12 +- examples/update-settings/tts/tts-aws-polly.py | 12 +- .../update-settings/tts/tts-azure-http.py | 12 +- examples/update-settings/tts/tts-azure.py | 12 +- examples/update-settings/tts/tts-camb.py | 12 +- .../update-settings/tts/tts-cartesia-http.py | 12 +- examples/update-settings/tts/tts-cartesia.py | 12 +- .../update-settings/tts/tts-deepgram-http.py | 14 +- .../tts/tts-deepgram-sagemaker.py | 14 +- examples/update-settings/tts/tts-deepgram.py | 14 +- .../tts/tts-elevenlabs-http.py | 12 +- .../update-settings/tts/tts-elevenlabs.py | 14 +- examples/update-settings/tts/tts-fish.py | 12 +- examples/update-settings/tts/tts-gemini.py | 12 +- .../update-settings/tts/tts-google-http.py | 12 +- .../update-settings/tts/tts-google-stream.py | 12 +- examples/update-settings/tts/tts-gradium.py | 12 +- examples/update-settings/tts/tts-groq.py | 14 +- examples/update-settings/tts/tts-hume.py | 12 +- .../update-settings/tts/tts-inworld-http.py | 12 +- examples/update-settings/tts/tts-inworld.py | 12 +- examples/update-settings/tts/tts-kokoro.py | 12 +- examples/update-settings/tts/tts-lmnt.py | 14 +- examples/update-settings/tts/tts-minimax.py | 12 +- .../update-settings/tts/tts-neuphonic-http.py | 12 +- examples/update-settings/tts/tts-neuphonic.py | 12 +- examples/update-settings/tts/tts-nvidia.py | 12 +- examples/update-settings/tts/tts-openai.py | 12 +- .../update-settings/tts/tts-piper-http.py | 12 +- examples/update-settings/tts/tts-piper.py | 12 +- .../update-settings/tts/tts-resembleai.py | 12 +- examples/update-settings/tts/tts-rime-http.py | 12 +- examples/update-settings/tts/tts-rime.py | 14 +- .../update-settings/tts/tts-sarvam-http.py | 12 +- examples/update-settings/tts/tts-sarvam.py | 12 +- .../update-settings/tts/tts-speechmatics.py | 12 +- examples/update-settings/tts/tts-xtts.py | 12 +- .../video-avatar-heygen-transport.py | 10 +- .../video-avatar-heygen-video-service.py | 10 +- .../video-avatar-lemonslice-transport.py | 10 +- .../video-avatar-simli-video-service.py | 10 +- .../video-avatar-tavus-transport.py | 10 +- .../video-avatar-tavus-video-service.py | 10 +- .../video-processing-custom-video-track.py | 8 +- .../video-processing-gstreamer-filesrc.py | 8 +- ...video-processing-gstreamer-videotestsrc.py | 6 +- .../video-processing-local-mirror.py | 10 +- .../video-processing-mirror.py | 8 +- examples/video-processing/video-processing.py | 12 +- examples/vision/vision-anthropic.py | 10 +- examples/vision/vision-aws.py | 10 +- examples/vision/vision-gemini-flash.py | 10 +- examples/vision/vision-moondream.py | 10 +- .../vision/vision-openai-responses-http.py | 10 +- examples/vision/vision-openai-responses.py | 10 +- examples/vision/vision-openai.py | 10 +- examples/voice/voice-aicoustics.py | 10 +- .../voice/voice-assemblyai-turn-detection.py | 10 +- examples/voice/voice-assemblyai.py | 10 +- examples/voice/voice-asyncai-http.py | 10 +- examples/voice/voice-asyncai.py | 10 +- examples/voice/voice-aws-strands.py | 10 +- examples/voice/voice-aws.py | 10 +- examples/voice/voice-azure-http.py | 10 +- examples/voice/voice-azure.py | 10 +- examples/voice/voice-camb.py | 10 +- examples/voice/voice-cartesia-http.py | 10 +- examples/voice/voice-cartesia.py | 10 +- .../voice/voice-deepgram-flux-sagemaker.py | 10 +- examples/voice/voice-deepgram-flux.py | 10 +- examples/voice/voice-deepgram-http.py | 10 +- examples/voice/voice-deepgram-sagemaker.py | 10 +- examples/voice/voice-deepgram.py | 10 +- examples/voice/voice-elevenlabs-http.py | 10 +- examples/voice/voice-elevenlabs.py | 10 +- examples/voice/voice-fal.py | 10 +- examples/voice/voice-fish.py | 10 +- examples/voice/voice-gladia-vad.py | 10 +- examples/voice/voice-gladia.py | 10 +- examples/voice/voice-google-audio-in.py | 10 +- examples/voice/voice-google-gemini-tts.py | 10 +- examples/voice/voice-google-http.py | 10 +- examples/voice/voice-google-image.py | 10 +- examples/voice/voice-google.py | 10 +- examples/voice/voice-gradium.py | 10 +- examples/voice/voice-groq.py | 10 +- examples/voice/voice-hume.py | 10 +- examples/voice/voice-inworld-http.py | 10 +- examples/voice/voice-inworld.py | 10 +- examples/voice/voice-kokoro.py | 10 +- examples/voice/voice-krisp-viva.py | 10 +- examples/voice/voice-langchain.py | 10 +- examples/voice/voice-lmnt.py | 10 +- examples/voice/voice-minimax.py | 10 +- examples/voice/voice-mistral.py | 10 +- examples/voice/voice-neuphonic-http.py | 10 +- examples/voice/voice-neuphonic.py | 10 +- examples/voice/voice-nvidia-sagemaker.py | 10 +- examples/voice/voice-nvidia.py | 10 +- examples/voice/voice-openai-http.py | 10 +- examples/voice/voice-openai-responses-http.py | 10 +- examples/voice/voice-openai-responses.py | 10 +- examples/voice/voice-openai.py | 10 +- examples/voice/voice-piper.py | 10 +- examples/voice/voice-resemble.py | 10 +- examples/voice/voice-rime-http.py | 10 +- examples/voice/voice-rime.py | 10 +- examples/voice/voice-sarvam-http.py | 10 +- examples/voice/voice-sarvam.py | 12 +- examples/voice/voice-smallest.py | 10 +- examples/voice/voice-soniox.py | 10 +- examples/voice/voice-speechmatics-vad.py | 10 +- examples/voice/voice-speechmatics.py | 10 +- examples/voice/voice-xai-http.py | 10 +- examples/voice/voice-xai.py | 10 +- examples/voice/voice-xtts.py | 10 +- src/pipecat/bus/__init__.py | 54 +- src/pipecat/bus/bridge_processor.py | 50 +- src/pipecat/bus/bus.py | 14 +- src/pipecat/bus/local/async_queue.py | 6 +- src/pipecat/bus/messages.py | 112 +- src/pipecat/bus/network/__init__.py | 2 +- src/pipecat/bus/network/pgmq.py | 10 +- src/pipecat/bus/network/redis.py | 10 +- src/pipecat/bus/subscriber.py | 4 +- .../voicemail/voicemail_detector.py | 10 +- .../observers/startup_timing_observer.py | 6 +- .../observers/user_bot_latency_observer.py | 2 +- .../pipeline/{base_task.py => base_worker.py} | 532 ++++---- src/pipecat/pipeline/job_context.py | 76 +- src/pipecat/pipeline/job_decorator.py | 6 +- src/pipecat/pipeline/parallel_pipeline.py | 2 +- src/pipecat/pipeline/runner.py | 281 ++-- src/pipecat/pipeline/task.py | 1109 +--------------- src/pipecat/pipeline/task_ready_decorator.py | 61 - src/pipecat/pipeline/utils.py | 6 +- src/pipecat/pipeline/worker.py | 1136 +++++++++++++++++ .../{task_observer.py => worker_observer.py} | 26 +- .../pipeline/worker_ready_decorator.py | 61 + .../aggregators/llm_response_universal.py | 4 +- src/pipecat/processors/frame_processor.py | 56 +- src/pipecat/registry/__init__.py | 6 +- src/pipecat/registry/registry.py | 112 +- src/pipecat/registry/types.py | 34 +- src/pipecat/services/llm_service.py | 14 +- src/pipecat/tasks/llm/__init__.py | 18 - src/pipecat/tasks/proxy/websocket/__init__.py | 15 - src/pipecat/tests/utils.py | 10 +- src/pipecat/utils/tracing/tracing_context.py | 4 +- src/pipecat/workers/llm/__init__.py | 18 + .../llm/llm_context_worker.py} | 28 +- .../llm_task.py => workers/llm/llm_worker.py} | 64 +- .../{tasks => workers}/llm/tool_decorator.py | 4 +- .../{tasks => workers}/proxy/__init__.py | 4 +- .../workers/proxy/websocket/__init__.py | 15 + .../proxy/websocket/client.py | 90 +- .../proxy/websocket/server.py | 102 +- tests/test_app_resources.py | 70 +- tests/test_audio_buffer_processor.py | 2 +- ...{test_base_task.py => test_base_worker.py} | 556 ++++---- tests/test_bridge_processor.py | 38 +- tests/test_bus.py | 4 +- tests/test_job_group.py | 26 +- tests/test_llm_service.py | 2 +- .../{test_llm_task.py => test_llm_worker.py} | 16 +- tests/test_pgmq_bus.py | 14 +- tests/test_pipeline.py | 206 +-- tests/test_redis_bus.py | 16 +- tests/test_registry.py | 48 +- tests/test_runner.py | 62 +- tests/test_serializers.py | 8 +- tests/test_startup_timing_observer.py | 2 +- tests/test_turn_trace_observer.py | 4 +- tests/test_vonage_video_connector.py | 7 +- tests/test_websocket_proxy.py | 26 +- 394 files changed, 4602 insertions(+), 4487 deletions(-) rename examples/{multi-task => multi-worker}/README.md (66%) rename examples/{multi-task => multi-worker}/code-assistant/code-assistant.py (93%) rename examples/{multi-task => multi-worker}/code-assistant/code_worker.py (94%) rename examples/{multi-task => multi-worker}/distributed-handoff/pgmq-handoff/llm.py (87%) rename examples/{multi-task => multi-worker}/distributed-handoff/pgmq-handoff/main.py (90%) rename examples/{multi-task => multi-worker}/distributed-handoff/redis-handoff/llm.py (84%) rename examples/{multi-task => multi-worker}/distributed-handoff/redis-handoff/main.py (88%) rename examples/{multi-task => multi-worker}/env.example (100%) rename examples/{multi-task => multi-worker}/local-handoff/local-handoff-two-agents-tts.py (87%) rename examples/{multi-task => multi-worker}/local-handoff/local-handoff-two-agents.py (85%) rename examples/{multi-task => multi-worker}/parallel-debate/parallel-debate.py (91%) rename examples/{multi-task => multi-worker}/remote-proxy-assistant/assistant.py (89%) rename examples/{multi-task => multi-worker}/remote-proxy-assistant/main.py (85%) rename examples/{multi-task => multi-worker}/sensor-controller/sensor-controller.py (94%) rename examples/{multi-task => multi-worker}/sensor-controller/sensor.py (100%) rename src/pipecat/pipeline/{base_task.py => base_worker.py} (68%) delete mode 100644 src/pipecat/pipeline/task_ready_decorator.py create mode 100644 src/pipecat/pipeline/worker.py rename src/pipecat/pipeline/{task_observer.py => worker_observer.py} (90%) create mode 100644 src/pipecat/pipeline/worker_ready_decorator.py delete mode 100644 src/pipecat/tasks/llm/__init__.py delete mode 100644 src/pipecat/tasks/proxy/websocket/__init__.py create mode 100644 src/pipecat/workers/llm/__init__.py rename src/pipecat/{tasks/llm/llm_context_task.py => workers/llm/llm_context_worker.py} (79%) rename src/pipecat/{tasks/llm/llm_task.py => workers/llm/llm_worker.py} (85%) rename src/pipecat/{tasks => workers}/llm/tool_decorator.py (94%) rename src/pipecat/{tasks => workers}/proxy/__init__.py (65%) create mode 100644 src/pipecat/workers/proxy/websocket/__init__.py rename src/pipecat/{tasks => workers}/proxy/websocket/client.py (68%) rename src/pipecat/{tasks => workers}/proxy/websocket/server.py (63%) rename tests/{test_base_task.py => test_base_worker.py} (70%) rename tests/{test_llm_task.py => test_llm_worker.py} (95%) diff --git a/changelog/4493.added.md b/changelog/4493.added.md index cf8e47454..4d839db9a 100644 --- a/changelog/4493.added.md +++ b/changelog/4493.added.md @@ -1 +1 @@ -- Added `pipecat.tasks`, a task-based agent framework folded in from the standalone `pipecat-subagents` package. Tasks inherit from `BaseTask`, share a `TaskBus`, register in a `TaskRegistry`, and exchange typed work via `@job` handlers. `LLMTask` and `LLMContextTask` provide ready-made LLM-driven tasks. `PipelineRunner.spawn(task)` registers fire-and-forget tasks alongside the main pipeline task. +- Added `pipecat.workers`, a worker-based agent framework folded in from the standalone `pipecat-subagents` package. Workers inherit from `BaseWorker`, share a `WorkerBus`, register in a `WorkerRegistry`, and exchange typed work via `@job` handlers. `LLMWorker` and `LLMContextWorker` provide ready-made LLM-driven workers. `PipelineRunner.spawn(worker)` registers fire-and-forget workers alongside the main pipeline worker. diff --git a/changelog/4493.changed.2.md b/changelog/4493.changed.2.md index e4b294a7c..fa7ca8dad 100644 --- a/changelog/4493.changed.2.md +++ b/changelog/4493.changed.2.md @@ -1 +1 @@ -- ⚠️ `FrameProcessorSetup.pipeline_task` and `FunctionCallParams.pipeline_task` are now mandatory fields, and `FrameProcessor.pipeline_task` raises if read before `setup()` instead of returning `None`. Real-world code (frame processors set up by `PipelineTask`, tool handlers invoked by `LLMService`) is unaffected; only callers that construct these dataclasses by hand (typically tests) now have to supply a `pipeline_task` reference. +- ⚠️ `FrameProcessorSetup.pipeline_worker` and `FunctionCallParams.pipeline_worker` are now mandatory fields, and `FrameProcessor.pipeline_worker` raises if read before `setup()` instead of returning `None`. Real-world code (frame processors set up by `PipelineWorker`, tool handlers invoked by `LLMService`) is unaffected; only callers that construct these dataclasses by hand (typically tests) now have to supply a `pipeline_worker` reference. diff --git a/changelog/4493.changed.md b/changelog/4493.changed.md index 7975110e1..c49a1a965 100644 --- a/changelog/4493.changed.md +++ b/changelog/4493.changed.md @@ -1 +1 @@ -- `PipelineTask` now inherits from `BaseTask`, so every pipeline task is also a bus participant. It accepts a new optional `bridged=()` parameter that auto-wraps the pipeline with bus edge processors, letting the task exchange frames with other bridged tasks over the shared `TaskBus`. The bus is supplied by `PipelineRunner` via `task.attach(registry=..., bus=...)` instead of through the constructor. +- `PipelineWorker` now inherits from `BaseWorker`, so every pipeline worker is also a bus participant. It accepts a new optional `bridged=()` parameter that auto-wraps the pipeline with bus edge processors, letting the worker exchange frames with other bridged workers over the shared `WorkerBus`. The bus is supplied by `PipelineRunner` via `worker.attach(registry=..., bus=...)` instead of through the constructor. diff --git a/examples/audio/audio-bot-background-sound.py b/examples/audio/audio-bot-background-sound.py index 6417e5549..9bca91814 100644 --- a/examples/audio/audio-bot-background-sound.py +++ b/examples/audio/audio-bot-background-sound.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, MixerEnableFrame, MixerUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -105,7 +105,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -120,27 +120,27 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): logger.info(f"Listening for background sound for a bit...") await asyncio.sleep(5.0) logger.info(f"Reducing volume...") - await task.queue_frame(MixerUpdateSettingsFrame({"volume": 0.5})) + await worker.queue_frame(MixerUpdateSettingsFrame({"volume": 0.5})) await asyncio.sleep(5.0) logger.info(f"Disabling background sound for a bit...") - await task.queue_frame(MixerEnableFrame(False)) + await worker.queue_frame(MixerEnableFrame(False)) await asyncio.sleep(5.0) logger.info(f"Re-enabling background sound and starting bot...") - await task.queue_frame(MixerEnableFrame(True)) + await worker.queue_frame(MixerEnableFrame(True)) # Kick off the conversation. context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/audio/audio-recording.py b/examples/audio/audio-recording.py index 9ece2b796..b23632bf8 100644 --- a/examples/audio/audio-recording.py +++ b/examples/audio/audio-recording.py @@ -54,7 +54,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -146,7 +146,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -161,12 +161,12 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): # Start recording audio await audiobuffer.start_recording() # Start conversation - empty prompt to let LLM follow system instructions - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() # Handler for merged audio @audiobuffer.event_handler("on_audio_data") @@ -191,7 +191,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): await save_audio_file(bot_audio, bot_filename, sample_rate, 1) runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/audio/audio-sound-effects.py b/examples/audio/audio-sound-effects.py index 19ed85675..f83930214 100644 --- a/examples/audio/audio-sound-effects.py +++ b/examples/audio/audio-sound-effects.py @@ -20,7 +20,7 @@ from pipecat.frames.frames import ( ) from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineTask +from pipecat.pipeline.worker import PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -144,7 +144,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, ) @@ -153,17 +153,17 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frame(TTSSpeakFrame("Hi, I'm listening!")) + await worker.queue_frame(TTSSpeakFrame("Hi, I'm listening!")) await transport.send_audio(sounds["ding1.wav"]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/context-summarization/context-summarization-dedicated-llm.py b/examples/context-summarization/context-summarization-dedicated-llm.py index bc13e9c46..c4796d316 100644 --- a/examples/context-summarization/context-summarization-dedicated-llm.py +++ b/examples/context-summarization/context-summarization-dedicated-llm.py @@ -26,7 +26,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_context_summarizer import SummaryAppliedEvent from pipecat.processors.aggregators.llm_response_universal import ( @@ -198,7 +198,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -214,16 +214,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info("Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/context-summarization/context-summarization-google.py b/examples/context-summarization/context-summarization-google.py index 3b0daca32..6221f8281 100644 --- a/examples/context-summarization/context-summarization-google.py +++ b/examples/context-summarization/context-summarization-google.py @@ -24,7 +24,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_context_summarizer import SummaryAppliedEvent from pipecat.processors.aggregators.llm_response_universal import ( @@ -159,7 +159,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -175,16 +175,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info("Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/context-summarization/context-summarization-manual-openai.py b/examples/context-summarization/context-summarization-manual-openai.py index 23f70d97c..16d830685 100644 --- a/examples/context-summarization/context-summarization-manual-openai.py +++ b/examples/context-summarization/context-summarization-manual-openai.py @@ -26,7 +26,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMSummarizeContextFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -133,7 +133,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -149,16 +149,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info("Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/context-summarization/context-summarization-openai.py b/examples/context-summarization/context-summarization-openai.py index 05566f32b..f84da9691 100644 --- a/examples/context-summarization/context-summarization-openai.py +++ b/examples/context-summarization/context-summarization-openai.py @@ -24,7 +24,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_context_summarizer import SummaryAppliedEvent from pipecat.processors.aggregators.llm_response_universal import ( @@ -159,7 +159,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -175,16 +175,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info("Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/features/features-add-tool-change-messages.py b/examples/features/features-add-tool-change-messages.py index 4ad69a819..c7f460f57 100644 --- a/examples/features/features-add-tool-change-messages.py +++ b/examples/features/features-add-tool-change-messages.py @@ -56,7 +56,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMSetToolsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import NOT_GIVEN, LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -163,7 +163,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams(enable_metrics=True, enable_usage_metrics=True), idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, @@ -185,13 +185,13 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): "=== Phase 1: weather tool REMOVED. Keep asking about the weather " "to exercise hallucination scenarios. ===" ) - await task.queue_frame(LLMSetToolsFrame(tools=NOT_GIVEN)) + await worker.queue_frame(LLMSetToolsFrame(tools=NOT_GIVEN)) elif user_turn_count == READD_AT_TURN - 1: logger.info( "=== Phase 2: weather tool RE-ADDED. Ask for the weather again — " "does the LLM call it, or keep refusing? (THIS IS THE TEST.) ===" ) - await task.queue_frame(LLMSetToolsFrame(tools=weather_tools)) + await worker.queue_frame(LLMSetToolsFrame(tools=weather_tools)) @transport.event_handler("on_client_connected") async def on_client_connected(transport, client): @@ -209,15 +209,15 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ), } ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info("Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/features/features-app-resources.py b/examples/features/features-app-resources.py index dc07f30e5..c5e21d42c 100644 --- a/examples/features/features-app-resources.py +++ b/examples/features/features-app-resources.py @@ -4,27 +4,27 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""Example demonstrating ``PipelineTask(app_resources=...)``. +"""Example demonstrating ``PipelineWorker(app_resources=...)``. ``app_resources`` is an application-defined bag of anything your application code may want to share across a session: database handles, HTTP clients, feature flags, per-user state, observability clients, in-memory caches — whatever fits your app. Pipecat passes it through -untouched and exposes it as ``task.app_resources``, so any code with a -handle on the task can read or mutate it. +untouched and exposes it as ``worker.app_resources``, so any code with a +handle on the worker can read or mutate it. Two of the convenience aliases exercised below: - Tool handlers read it from ``FunctionCallParams.app_resources``. - Custom ``FrameProcessor`` subclasses read it from - ``self.pipeline_task.app_resources``. + ``self.pipeline_worker.app_resources``. This example uses two small loggers as stand-ins for that "shared thing": ``ToolCallLogger`` (written from tool handlers) and ``TranscriptionLogger`` (written from a custom ``FrameProcessor`` that sits in the pipeline). A real app might just as easily pass a Postgres pool, a Redis client, a Stripe SDK instance, or any combination thereof. -The mechanics shown here — construct once, hand to the task, read it +The mechanics shown here — construct once, hand to the worker, read it from each site, inspect it after the session — are the same regardless of what you put in. @@ -50,7 +50,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import Frame, LLMRunFrame, TranscriptionFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -131,7 +131,7 @@ class AppResources: get autocomplete and refactor safety: - In tools: ``cast(AppResources, params.app_resources)``. - - In custom processors: ``cast(AppResources, self.pipeline_task.app_resources)``. + - In custom processors: ``cast(AppResources, self.pipeline_worker.app_resources)``. """ tool_call_logger: ToolCallLogger @@ -155,8 +155,8 @@ class TranscriptionLoggingProcessor(FrameProcessor): Demonstrates the second read site for ``app_resources``: any custom ``FrameProcessor`` can reach the same bag every tool handler sees by - going through ``self.pipeline_task.app_resources``. ``pipeline_task`` - is ``None`` until the task sets the processor up, so we guard against + going through ``self.pipeline_worker.app_resources``. ``pipeline_worker`` + is ``None`` until the worker sets the processor up, so we guard against that case. """ @@ -164,8 +164,8 @@ class TranscriptionLoggingProcessor(FrameProcessor): """Forward all frames; log final user transcriptions on the way through.""" await super().process_frame(frame, direction) - if isinstance(frame, TranscriptionFrame) and self.pipeline_task is not None: - resources = cast(AppResources, self.pipeline_task.app_resources) + if isinstance(frame, TranscriptionFrame) and self.pipeline_worker is not None: + resources = cast(AppResources, self.pipeline_worker.app_resources) resources.transcription_logger.log_transcription(frame.text) await self.push_frame(frame, direction) @@ -282,7 +282,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): transcription_logger=transcription_logger, ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -299,16 +299,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) # The session has ended; read whatever state the handlers built up. logger.info(f"Tool calls logged during session:\n{tool_call_logger.dump()}") diff --git a/examples/features/features-before-and-after-events.py b/examples/features/features-before-and-after-events.py index dedf3c4fa..5cf89afdf 100644 --- a/examples/features/features-before-and-after-events.py +++ b/examples/features/features-before-and-after-events.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import DataFrame, LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -97,7 +97,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -124,16 +124,18 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): {"role": "developer", "content": "Please introduce yourself to the user."} ) # Custom frames are pushed in order so they can be used for synchronization purposes. - await task.queue_frames([CustomBeforeProcessFrame(), LLMRunFrame(), CustomAfterPushFrame()]) + await worker.queue_frames( + [CustomBeforeProcessFrame(), LLMRunFrame(), CustomAfterPushFrame()] + ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/features/features-concurrent-llm-evaluation.py b/examples/features/features-concurrent-llm-evaluation.py index cb085a8c7..a7baba9c6 100644 --- a/examples/features/features-concurrent-llm-evaluation.py +++ b/examples/features/features-concurrent-llm-evaluation.py @@ -15,7 +15,7 @@ from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.parallel_pipeline import ParallelPipeline from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -130,7 +130,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -149,16 +149,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): groq_context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/features/features-concurrent-llm-rtvi-ignored-sources.py b/examples/features/features-concurrent-llm-rtvi-ignored-sources.py index 70530b51e..4a4effd6c 100644 --- a/examples/features/features-concurrent-llm-rtvi-ignored-sources.py +++ b/examples/features/features-concurrent-llm-rtvi-ignored-sources.py @@ -21,7 +21,7 @@ from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.parallel_pipeline import ParallelPipeline from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -141,7 +141,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -160,16 +160,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): evaluator_context.add_message( {"role": "developer", "content": "Ready to evaluate user messages."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info("Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/features/features-custom-frame-processor.py b/examples/features/features-custom-frame-processor.py index ab82bae80..b3712a372 100644 --- a/examples/features/features-custom-frame-processor.py +++ b/examples/features/features-custom-frame-processor.py @@ -17,7 +17,7 @@ from pipecat.frames.frames import ( ) from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -128,7 +128,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -144,16 +144,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/features/features-gpu-container-local-bot.py b/examples/features/features-gpu-container-local-bot.py index 67a8dabc7..40840fe92 100644 --- a/examples/features/features-gpu-container-local-bot.py +++ b/examples/features/features-gpu-container-local-bot.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -95,7 +95,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -112,7 +112,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) # Handle "latency-ping" messages. The client will send app messages that look like # this: @@ -128,13 +128,13 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): logger.debug(f"Received latency ping app message: {message}") ts = message["latency-ping"]["ts"] # Send immediately - await task.queue_frame( + await worker.queue_frame( DailyOutputTransportMessageUrgentFrame( message={"latency-pong-msg-handler": {"ts": ts}}, participant_id=sender ) ) # And push to the pipeline for the Daily transport.output to send - await task.queue_frame( + await worker.queue_frame( DailyOutputTransportMessageFrame( message={"latency-pong-pipeline-delivery": {"ts": ts}}, participant_id=sender, @@ -146,11 +146,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/features/features-live-translation.py b/examples/features/features-live-translation.py index e4e7d075f..2adbe3b64 100644 --- a/examples/features/features-live-translation.py +++ b/examples/features/features-live-translation.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -99,7 +99,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -111,7 +111,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_connected") async def on_client_connected(transport, client): logger.info(f"Client connected") - await task.queue_frames( + await worker.queue_frames( [ TTSSpeakFrame( text="Hello, welcome to live translation. Everything you say will be automatically translated to Spanish. Let's begin!", @@ -123,11 +123,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/features/features-pattern-pair-voice-switching.py b/examples/features/features-pattern-pair-voice-switching.py index 1f5b83cb8..aab61faf5 100644 --- a/examples/features/features-pattern-pair-voice-switching.py +++ b/examples/features/features-pattern-pair-voice-switching.py @@ -48,7 +48,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -216,7 +216,7 @@ Remember: Use narrator voice for EVERYTHING except the actual quoted dialogue."" ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -229,15 +229,15 @@ Remember: Use narrator voice for EVERYTHING except the actual quoted dialogue."" async def on_client_connected(transport, client): logger.info(f"Client connected") # Start conversation - empty prompt to let LLM follow system instructions - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/features/features-service-switcher.py b/examples/features/features-service-switcher.py index c2c78738a..b7f6c14b7 100644 --- a/examples/features/features-service-switcher.py +++ b/examples/features/features-service-switcher.py @@ -18,7 +18,7 @@ from pipecat.pipeline.llm_switcher import LLMSwitcher from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner from pipecat.pipeline.service_switcher import ServiceSwitcher -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -151,7 +151,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -167,25 +167,25 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(15) print(f"Switching to {stt_deepgram}") - await task.queue_frames([ManuallySwitchServiceFrame(service=stt_deepgram)]) + await worker.queue_frames([ManuallySwitchServiceFrame(service=stt_deepgram)]) await asyncio.sleep(15) print(f"Switching to {llm_google}") - await task.queue_frames([ManuallySwitchServiceFrame(service=llm_google)]) + await worker.queue_frames([ManuallySwitchServiceFrame(service=llm_google)]) await asyncio.sleep(15) print(f"Switching to {tts_deepgram}") - await task.queue_frames([ManuallySwitchServiceFrame(service=tts_deepgram)]) + await worker.queue_frames([ManuallySwitchServiceFrame(service=tts_deepgram)]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/features/features-switch-languages.py b/examples/features/features-switch-languages.py index f99de0aec..b63b1084f 100644 --- a/examples/features/features-switch-languages.py +++ b/examples/features/features-switch-languages.py @@ -17,7 +17,7 @@ from pipecat.frames.frames import Frame, LLMRunFrame from pipecat.pipeline.parallel_pipeline import ParallelPipeline from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -147,7 +147,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -166,16 +166,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): "content": f"Please introduce yourself to the user and let them know the languages you speak. Your initial responses should be in {tts.current_language}.", } ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/features/features-switch-voices.py b/examples/features/features-switch-voices.py index d33a10e8f..c86151a07 100644 --- a/examples/features/features-switch-voices.py +++ b/examples/features/features-switch-voices.py @@ -17,7 +17,7 @@ from pipecat.frames.frames import Frame, LLMRunFrame from pipecat.pipeline.parallel_pipeline import ParallelPipeline from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -157,7 +157,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -176,16 +176,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): "content": f"Please introduce yourself to the user and let them know the voices you can do. Your initial responses should be as if you were a {tts.current_voice}.", } ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/features/features-user-email-gathering.py b/examples/features/features-user-email-gathering.py index f0ec3160f..d989c7ddd 100644 --- a/examples/features/features-user-email-gathering.py +++ b/examples/features/features-user-email-gathering.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -125,7 +125,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -138,15 +138,15 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Start conversation - empty prompt to let LLM follow system instructions - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/features/features-voicemail-detection.py b/examples/features/features-voicemail-detection.py index 4c8f07d6e..c59042066 100644 --- a/examples/features/features-voicemail-detection.py +++ b/examples/features/features-voicemail-detection.py @@ -14,7 +14,7 @@ from pipecat.extensions.voicemail.voicemail_detector import VoicemailDetector from pipecat.frames.frames import TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -91,7 +91,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -107,7 +107,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() @voicemail.event_handler("on_conversation_detected") async def on_conversation_detected(processor): @@ -130,7 +130,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/features/features-wake-phrase.py b/examples/features/features-wake-phrase.py index 8d39d5c60..a7e77bad7 100644 --- a/examples/features/features-wake-phrase.py +++ b/examples/features/features-wake-phrase.py @@ -13,7 +13,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -107,7 +107,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -123,16 +123,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-anthropic-async-stream.py b/examples/function-calling/function-calling-anthropic-async-stream.py index b44bb5997..fc5b0327e 100644 --- a/examples/function-calling/function-calling-anthropic-async-stream.py +++ b/examples/function-calling/function-calling-anthropic-async-stream.py @@ -38,7 +38,7 @@ from pipecat.frames.frames import ( ) from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -171,7 +171,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -186,16 +186,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-anthropic-async.py b/examples/function-calling/function-calling-anthropic-async.py index 5046ec839..a82abc2cb 100644 --- a/examples/function-calling/function-calling-anthropic-async.py +++ b/examples/function-calling/function-calling-anthropic-async.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -140,7 +140,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -156,16 +156,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-anthropic-video.py b/examples/function-calling/function-calling-anthropic-video.py index 1b7617950..fb96a985e 100644 --- a/examples/function-calling/function-calling-anthropic-video.py +++ b/examples/function-calling/function-calling-anthropic-video.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame, UserImageRequestFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -143,7 +143,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -168,16 +168,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): "content": f"Please introduce yourself to the user. Use '{client_id}' as the user ID during function calls.", } ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-anthropic.py b/examples/function-calling/function-calling-anthropic.py index 3c4cf769a..efd0f6f77 100644 --- a/examples/function-calling/function-calling-anthropic.py +++ b/examples/function-calling/function-calling-anthropic.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -125,7 +125,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -141,16 +141,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-aws-video.py b/examples/function-calling/function-calling-aws-video.py index d6ae64438..2a92b70c2 100644 --- a/examples/function-calling/function-calling-aws-video.py +++ b/examples/function-calling/function-calling-aws-video.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame, UserImageRequestFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -148,7 +148,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -173,16 +173,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): "content": f"Please introduce yourself to the user briefly; don't mention the camera. Use '{client_id}' as the user ID during function calls.", } ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-aws.py b/examples/function-calling/function-calling-aws.py index b8425a341..abb853180 100644 --- a/examples/function-calling/function-calling-aws.py +++ b/examples/function-calling/function-calling-aws.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -134,7 +134,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -150,16 +150,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-azure.py b/examples/function-calling/function-calling-azure.py index 37d67b29b..d6f3305cb 100644 --- a/examples/function-calling/function-calling-azure.py +++ b/examples/function-calling/function-calling-azure.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -120,7 +120,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -133,16 +133,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-cerebras.py b/examples/function-calling/function-calling-cerebras.py index 82d98d40e..2bde84d92 100644 --- a/examples/function-calling/function-calling-cerebras.py +++ b/examples/function-calling/function-calling-cerebras.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -129,7 +129,7 @@ Start by asking me for my location. Then, use 'get_weather_current' to give me a ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -142,16 +142,16 @@ Start by asking me for my location. Then, use 'get_weather_current' to give me a async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-deepseek.py b/examples/function-calling/function-calling-deepseek.py index fc354ccf5..232116c22 100644 --- a/examples/function-calling/function-calling-deepseek.py +++ b/examples/function-calling/function-calling-deepseek.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -130,7 +130,7 @@ Start by asking me for my location. Then, use 'get_weather_current' to give me a ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -143,16 +143,16 @@ Start by asking me for my location. Then, use 'get_weather_current' to give me a async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-direct.py b/examples/function-calling/function-calling-direct.py index c885d6606..fafae9ab7 100644 --- a/examples/function-calling/function-calling-direct.py +++ b/examples/function-calling/function-calling-direct.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -121,7 +121,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -134,16 +134,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-fireworks.py b/examples/function-calling/function-calling-fireworks.py index 8c681fa72..bfbd35c88 100644 --- a/examples/function-calling/function-calling-fireworks.py +++ b/examples/function-calling/function-calling-fireworks.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -123,7 +123,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -139,16 +139,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-google-async-stream.py b/examples/function-calling/function-calling-google-async-stream.py index 1660442b4..0819580ce 100644 --- a/examples/function-calling/function-calling-google-async-stream.py +++ b/examples/function-calling/function-calling-google-async-stream.py @@ -38,7 +38,7 @@ from pipecat.frames.frames import ( ) from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -175,7 +175,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -190,16 +190,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-google-async.py b/examples/function-calling/function-calling-google-async.py index f3c5fbc1d..c7ff23d14 100644 --- a/examples/function-calling/function-calling-google-async.py +++ b/examples/function-calling/function-calling-google-async.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame, UserImageRequestFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -208,7 +208,7 @@ indicate you should use the get_image tool are: ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -232,16 +232,16 @@ indicate you should use the get_image tool are: "content": f"Please introduce yourself to the user. Use '{client_id}' as the user ID during function calls.", } ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-google-vertex.py b/examples/function-calling/function-calling-google-vertex.py index 290315f2c..bf65628c1 100644 --- a/examples/function-calling/function-calling-google-vertex.py +++ b/examples/function-calling/function-calling-google-vertex.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -121,7 +121,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -140,16 +140,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): "content": "Please introduce yourself to the user.", } ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-google-video.py b/examples/function-calling/function-calling-google-video.py index 65296c603..069176903 100644 --- a/examples/function-calling/function-calling-google-video.py +++ b/examples/function-calling/function-calling-google-video.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame, UserImageRequestFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -143,7 +143,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -168,16 +168,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): "content": f"Please introduce yourself to the user. Use '{client_id}' as the user ID during function calls.", } ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-google.py b/examples/function-calling/function-calling-google.py index 1b6d5b152..d610ce1af 100644 --- a/examples/function-calling/function-calling-google.py +++ b/examples/function-calling/function-calling-google.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame, UserImageRequestFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -200,7 +200,7 @@ indicate you should use the get_image tool are: ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -224,16 +224,16 @@ indicate you should use the get_image tool are: "content": f"Please introduce yourself to the user. Use '{client_id}' as the user ID during function calls.", } ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-grok.py b/examples/function-calling/function-calling-grok.py index 537ab2025..6b82822dd 100644 --- a/examples/function-calling/function-calling-grok.py +++ b/examples/function-calling/function-calling-grok.py @@ -17,7 +17,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -117,7 +117,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -133,16 +133,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-groq.py b/examples/function-calling/function-calling-groq.py index d4c69349e..2e2a71897 100644 --- a/examples/function-calling/function-calling-groq.py +++ b/examples/function-calling/function-calling-groq.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -118,7 +118,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -131,16 +131,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-missing-handler.py b/examples/function-calling/function-calling-missing-handler.py index 6862ac067..2f4f69f1f 100644 --- a/examples/function-calling/function-calling-missing-handler.py +++ b/examples/function-calling/function-calling-missing-handler.py @@ -48,7 +48,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -141,7 +141,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams(enable_metrics=True, enable_usage_metrics=True), idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, @@ -164,15 +164,15 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ), } ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info("Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-mistral.py b/examples/function-calling/function-calling-mistral.py index e44adf8ba..9fb38d537 100644 --- a/examples/function-calling/function-calling-mistral.py +++ b/examples/function-calling/function-calling-mistral.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -131,7 +131,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -144,16 +144,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-moondream-video.py b/examples/function-calling/function-calling-moondream-video.py index 56a0fa503..4f5b5501c 100644 --- a/examples/function-calling/function-calling-moondream-video.py +++ b/examples/function-calling/function-calling-moondream-video.py @@ -24,7 +24,7 @@ from pipecat.frames.frames import ( from pipecat.pipeline.parallel_pipeline import ParallelPipeline from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineTask +from pipecat.pipeline.worker import PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -185,7 +185,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, ) @@ -206,16 +206,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): "content": f"Please introduce yourself to the user. Use '{client_id}' as the user ID during function calls.", } ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-nebius.py b/examples/function-calling/function-calling-nebius.py index ed8fded2c..c310ca0ea 100644 --- a/examples/function-calling/function-calling-nebius.py +++ b/examples/function-calling/function-calling-nebius.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -135,7 +135,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -151,16 +151,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-novita.py b/examples/function-calling/function-calling-novita.py index d9838e37f..8c4cde870 100644 --- a/examples/function-calling/function-calling-novita.py +++ b/examples/function-calling/function-calling-novita.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -136,7 +136,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -149,16 +149,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-nvidia.py b/examples/function-calling/function-calling-nvidia.py index 2b4818ceb..157f6485c 100644 --- a/examples/function-calling/function-calling-nvidia.py +++ b/examples/function-calling/function-calling-nvidia.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -122,7 +122,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -135,16 +135,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-ollama.py b/examples/function-calling/function-calling-ollama.py index ec6c3948a..6a4a175e9 100644 --- a/examples/function-calling/function-calling-ollama.py +++ b/examples/function-calling/function-calling-ollama.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -136,7 +136,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -149,16 +149,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-openai-async-stream.py b/examples/function-calling/function-calling-openai-async-stream.py index b1d9d724b..7b9c9d9b3 100644 --- a/examples/function-calling/function-calling-openai-async-stream.py +++ b/examples/function-calling/function-calling-openai-async-stream.py @@ -38,7 +38,7 @@ from pipecat.frames.frames import ( ) from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -175,7 +175,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -190,16 +190,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-openai-async.py b/examples/function-calling/function-calling-openai-async.py index de0d1a014..67cc55a3c 100644 --- a/examples/function-calling/function-calling-openai-async.py +++ b/examples/function-calling/function-calling-openai-async.py @@ -19,7 +19,7 @@ from pipecat.frames.frames import ( ) from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -153,7 +153,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -168,16 +168,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-openai-responses-async-stream.py b/examples/function-calling/function-calling-openai-responses-async-stream.py index 4007c21eb..f88e6ceb9 100644 --- a/examples/function-calling/function-calling-openai-responses-async-stream.py +++ b/examples/function-calling/function-calling-openai-responses-async-stream.py @@ -38,7 +38,7 @@ from pipecat.frames.frames import ( ) from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -175,7 +175,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -187,16 +187,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-openai-responses-async.py b/examples/function-calling/function-calling-openai-responses-async.py index f7e6d370b..395bc89ed 100644 --- a/examples/function-calling/function-calling-openai-responses-async.py +++ b/examples/function-calling/function-calling-openai-responses-async.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -157,7 +157,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -173,16 +173,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-openai-responses-http.py b/examples/function-calling/function-calling-openai-responses-http.py index e27d5d82b..0ebca3433 100644 --- a/examples/function-calling/function-calling-openai-responses-http.py +++ b/examples/function-calling/function-calling-openai-responses-http.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -135,7 +135,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -151,16 +151,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-openai-responses-video-http.py b/examples/function-calling/function-calling-openai-responses-video-http.py index 9d9953359..b600bf173 100644 --- a/examples/function-calling/function-calling-openai-responses-video-http.py +++ b/examples/function-calling/function-calling-openai-responses-video-http.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame, UserImageRequestFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -143,7 +143,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -167,12 +167,12 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): "content": f"Please introduce yourself to the user. Use '{client_id}' as the user ID during function calls.", } ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() @tts.event_handler("on_tts_request") async def on_tts_request(tts, context_id: str, text: str): @@ -180,7 +180,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-openai-responses-video.py b/examples/function-calling/function-calling-openai-responses-video.py index 3cb159a3f..358cbb774 100644 --- a/examples/function-calling/function-calling-openai-responses-video.py +++ b/examples/function-calling/function-calling-openai-responses-video.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame, UserImageRequestFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -143,7 +143,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -167,12 +167,12 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): "content": f"Please introduce yourself to the user. Use '{client_id}' as the user ID during function calls.", } ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() @tts.event_handler("on_tts_request") async def on_tts_request(tts, context_id: str, text: str): @@ -180,7 +180,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-openai-responses.py b/examples/function-calling/function-calling-openai-responses.py index 97481d01e..344de7ae2 100644 --- a/examples/function-calling/function-calling-openai-responses.py +++ b/examples/function-calling/function-calling-openai-responses.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -143,7 +143,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -159,16 +159,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-openai-video.py b/examples/function-calling/function-calling-openai-video.py index 8ca7725b0..63d0c46e8 100644 --- a/examples/function-calling/function-calling-openai-video.py +++ b/examples/function-calling/function-calling-openai-video.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame, UserImageRequestFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -143,7 +143,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -167,12 +167,12 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): "content": f"Please introduce yourself to the user. Use '{client_id}' as the user ID during function calls.", } ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() @tts.event_handler("on_tts_request") async def on_tts_request(tts, context_id: str, text: str): @@ -180,7 +180,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-openai.py b/examples/function-calling/function-calling-openai.py index 20777eaca..72f093279 100644 --- a/examples/function-calling/function-calling-openai.py +++ b/examples/function-calling/function-calling-openai.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -136,7 +136,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -148,16 +148,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-openrouter.py b/examples/function-calling/function-calling-openrouter.py index 299846133..ddb5a88a8 100644 --- a/examples/function-calling/function-calling-openrouter.py +++ b/examples/function-calling/function-calling-openrouter.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -123,7 +123,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -136,16 +136,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-perplexity.py b/examples/function-calling/function-calling-perplexity.py index 8abbc3618..345ef1df4 100644 --- a/examples/function-calling/function-calling-perplexity.py +++ b/examples/function-calling/function-calling-perplexity.py @@ -20,7 +20,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -92,7 +92,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -108,16 +108,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-qwen.py b/examples/function-calling/function-calling-qwen.py index 78aa48adf..c11c902da 100644 --- a/examples/function-calling/function-calling-qwen.py +++ b/examples/function-calling/function-calling-qwen.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -121,7 +121,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -134,16 +134,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-sambanova.py b/examples/function-calling/function-calling-sambanova.py index 528c4fc47..098c84c43 100644 --- a/examples/function-calling/function-calling-sambanova.py +++ b/examples/function-calling/function-calling-sambanova.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -120,7 +120,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -133,16 +133,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-sarvam.py b/examples/function-calling/function-calling-sarvam.py index 830860a9a..c5cc9e489 100644 --- a/examples/function-calling/function-calling-sarvam.py +++ b/examples/function-calling/function-calling-sarvam.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -140,7 +140,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -156,16 +156,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/function-calling/function-calling-together.py b/examples/function-calling/function-calling-together.py index e785588f4..42df074aa 100644 --- a/examples/function-calling/function-calling-together.py +++ b/examples/function-calling/function-calling-together.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -118,7 +118,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -134,16 +134,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/getting-started/01-say-one-thing.py b/examples/getting-started/01-say-one-thing.py index 1c6e1c703..774bfa1de 100644 --- a/examples/getting-started/01-say-one-thing.py +++ b/examples/getting-started/01-say-one-thing.py @@ -12,7 +12,7 @@ from loguru import logger from pipecat.frames.frames import EndFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineTask +from pipecat.pipeline.worker import PipelineWorker from pipecat.runner.types import RunnerArguments from pipecat.runner.utils import create_transport from pipecat.services.cartesia.tts import CartesiaTTSService @@ -42,7 +42,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ), ) - task = PipelineTask( + worker = PipelineWorker( Pipeline([tts, transport.output()]), idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, ) @@ -50,11 +50,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): # Register an event handler so we can play the audio when the client joins @transport.event_handler("on_client_connected") async def on_client_connected(transport, client): - await task.queue_frames([TTSSpeakFrame(f"Hello there!"), EndFrame()]) + await worker.queue_frames([TTSSpeakFrame(f"Hello there!"), EndFrame()]) runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/getting-started/01a-local-audio.py b/examples/getting-started/01a-local-audio.py index 02a489c93..1355998cb 100644 --- a/examples/getting-started/01a-local-audio.py +++ b/examples/getting-started/01a-local-audio.py @@ -14,7 +14,7 @@ from loguru import logger from pipecat.frames.frames import EndFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineTask +from pipecat.pipeline.worker import PipelineWorker from pipecat.services.cartesia.tts import CartesiaTTSService from pipecat.transports.local.audio import LocalAudioTransport, LocalAudioTransportParams @@ -36,15 +36,15 @@ async def main(): pipeline = Pipeline([tts, transport.output()]) - task = PipelineTask(pipeline) + worker = PipelineWorker(pipeline) async def say_something(): await asyncio.sleep(1) - await task.queue_frames([TTSSpeakFrame("Hello there, how is it going!"), EndFrame()]) + await worker.queue_frames([TTSSpeakFrame("Hello there, how is it going!"), EndFrame()]) runner = PipelineRunner(handle_sigint=False if sys.platform == "win32" else True) - await asyncio.gather(runner.run(task), say_something()) + await asyncio.gather(runner.run(worker), say_something()) if __name__ == "__main__": diff --git a/examples/getting-started/02-llm-say-one-thing.py b/examples/getting-started/02-llm-say-one-thing.py index df52772cf..d65965cad 100644 --- a/examples/getting-started/02-llm-say-one-thing.py +++ b/examples/getting-started/02-llm-say-one-thing.py @@ -12,7 +12,7 @@ from loguru import logger from pipecat.frames.frames import EndFrame, LLMContextFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineTask +from pipecat.pipeline.worker import PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.runner.types import RunnerArguments from pipecat.runner.utils import create_transport @@ -51,7 +51,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ), ) - task = PipelineTask( + worker = PipelineWorker( Pipeline([llm, tts, transport.output()]), idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, ) @@ -61,11 +61,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): context = LLMContext() context.add_message({"role": "developer", "content": "Say hello to the world."}) - await task.queue_frames([LLMContextFrame(context), EndFrame()]) + await worker.queue_frames([LLMContextFrame(context), EndFrame()]) runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/getting-started/03-still-frame.py b/examples/getting-started/03-still-frame.py index 61b211499..f90fde3f7 100644 --- a/examples/getting-started/03-still-frame.py +++ b/examples/getting-started/03-still-frame.py @@ -12,7 +12,7 @@ from loguru import logger from pipecat.frames.frames import TextFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.runner.types import RunnerArguments from pipecat.runner.utils import create_transport from pipecat.services.google.image import GoogleImageGenService @@ -45,7 +45,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): api_key=os.environ["GOOGLE_API_KEY"], ) - task = PipelineTask( + worker = PipelineWorker( Pipeline([imagegen, transport.output()]), params=PipelineParams( enable_metrics=True, @@ -57,18 +57,18 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): # Register an event handler so we can play the audio when the client joins @transport.event_handler("on_client_connected") async def on_client_connected(transport, client): - await task.queue_frame(TextFrame("a cat in the style of picasso")) - await task.queue_frame(TextFrame("a dog in the style of picasso")) - await task.queue_frame(TextFrame("a fish in the style of picasso")) + await worker.queue_frame(TextFrame("a cat in the style of picasso")) + await worker.queue_frame(TextFrame("a dog in the style of picasso")) + await worker.queue_frame(TextFrame("a fish in the style of picasso")) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/getting-started/03a-local-still-frame.py b/examples/getting-started/03a-local-still-frame.py index 0b70e2297..ef1302713 100644 --- a/examples/getting-started/03a-local-still-frame.py +++ b/examples/getting-started/03a-local-still-frame.py @@ -16,7 +16,7 @@ from loguru import logger from pipecat.frames.frames import TextFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineTask +from pipecat.pipeline.worker import PipelineWorker from pipecat.services.fal.image import FalImageGenService from pipecat.transports.local.tk import TkLocalTransport, TkTransportParams @@ -46,18 +46,18 @@ async def main(): pipeline = Pipeline([imagegen, transport.output()]) - task = PipelineTask(pipeline) - await task.queue_frames([TextFrame("a cat in the style of picasso")]) + worker = PipelineWorker(pipeline) + await worker.queue_frames([TextFrame("a cat in the style of picasso")]) runner = PipelineRunner() async def run_tk(): - while not task.has_finished(): + while not worker.has_finished(): tk_root.update() tk_root.update_idletasks() await asyncio.sleep(0.1) - await asyncio.gather(runner.run(task), run_tk()) + await asyncio.gather(runner.run(worker), run_tk()) if __name__ == "__main__": diff --git a/examples/getting-started/04-sync-speech-and-image.py b/examples/getting-started/04-sync-speech-and-image.py index c26bb324e..96630a6b3 100644 --- a/examples/getting-started/04-sync-speech-and-image.py +++ b/examples/getting-started/04-sync-speech-and-image.py @@ -22,7 +22,7 @@ from pipecat.frames.frames import ( from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner from pipecat.pipeline.sync_parallel_pipeline import FrameOrder, SyncParallelPipeline -from pipecat.pipeline.task import PipelineTask +from pipecat.pipeline.worker import PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.sentence import SentenceAggregator from pipecat.processors.frame_processor import FrameDirection, FrameProcessor @@ -186,7 +186,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): frames.append(MonthFrame(month=month)) frames.append(LLMContextFrame(LLMContext(messages))) - task = PipelineTask( + worker = PipelineWorker( pipeline, idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, ) @@ -196,16 +196,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Start the month narration once connected - await task.queue_frames(frames) + await worker.queue_frames(frames) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() # Run the pipeline runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/getting-started/05-speaking-state.py b/examples/getting-started/05-speaking-state.py index 32206d1b0..58a098fc1 100644 --- a/examples/getting-started/05-speaking-state.py +++ b/examples/getting-started/05-speaking-state.py @@ -20,7 +20,7 @@ from pipecat.frames.frames import ( ) from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -136,7 +136,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -149,15 +149,15 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/getting-started/06-voice-agent.py b/examples/getting-started/06-voice-agent.py index c9fe1cf12..4031675f5 100644 --- a/examples/getting-started/06-voice-agent.py +++ b/examples/getting-started/06-voice-agent.py @@ -13,7 +13,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -85,7 +85,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -101,16 +101,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/getting-started/06a-voice-agent-local.py b/examples/getting-started/06a-voice-agent-local.py index 8864f7aff..08d2c3ce7 100644 --- a/examples/getting-started/06a-voice-agent-local.py +++ b/examples/getting-started/06a-voice-agent-local.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -74,7 +74,7 @@ async def main(): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -83,11 +83,11 @@ async def main(): ) context.add_message({"role": "developer", "content": "Please introduce yourself to the user."}) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) runner = PipelineRunner() - await runner.run(task) + await runner.run(worker) if __name__ == "__main__": diff --git a/examples/getting-started/07-function-calling.py b/examples/getting-started/07-function-calling.py index 173f6a6fe..0e9b4c00c 100644 --- a/examples/getting-started/07-function-calling.py +++ b/examples/getting-started/07-function-calling.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -135,7 +135,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -151,16 +151,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/mcp/mcp-multiple-mcp.py b/examples/mcp/mcp-multiple-mcp.py index 8d7717291..c64d54db7 100644 --- a/examples/mcp/mcp-multiple-mcp.py +++ b/examples/mcp/mcp-multiple-mcp.py @@ -18,7 +18,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -130,7 +130,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -143,16 +143,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected: {client}") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/mcp/mcp-stdio.py b/examples/mcp/mcp-stdio.py index a93463ede..235f9e1e8 100644 --- a/examples/mcp/mcp-stdio.py +++ b/examples/mcp/mcp-stdio.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -108,7 +108,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -121,16 +121,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected: {client}") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/mcp/mcp-streamable-http-gemini-live.py b/examples/mcp/mcp-streamable-http-gemini-live.py index 213667e7a..51b8dab92 100644 --- a/examples/mcp/mcp-streamable-http-gemini-live.py +++ b/examples/mcp/mcp-streamable-http-gemini-live.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -97,7 +97,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -110,16 +110,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected: {client}") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/mcp/mcp-streamable-http.py b/examples/mcp/mcp-streamable-http.py index b4823c649..5d2572e74 100644 --- a/examples/mcp/mcp-streamable-http.py +++ b/examples/mcp/mcp-streamable-http.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -112,7 +112,7 @@ Just respond with short sentences when you are carrying out tool calls. ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -125,16 +125,16 @@ Just respond with short sentences when you are carrying out tool calls. async def on_client_connected(transport, client): logger.info(f"Client connected: {client}") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/multi-task/README.md b/examples/multi-worker/README.md similarity index 66% rename from examples/multi-task/README.md rename to examples/multi-worker/README.md index ca1b67dc1..fdb938165 100644 --- a/examples/multi-task/README.md +++ b/examples/multi-worker/README.md @@ -1,6 +1,6 @@ -# Pipecat Multi-Task Examples +# Pipecat Multi-Worker Examples -This directory contains example bots that use the multi-task framework in `pipecat.tasks`, `pipecat.pipeline.runner` (with `spawn()`), and the `TaskBus`. Each example shows a different cooperation pattern between tasks: hand-off, parallel fan-out, remote workers, etc. +This directory contains example bots that use the multi-worker framework in `pipecat.workers`, `pipecat.pipeline.runner` (with `add_worker()`), and the `WorkerBus`. Each example shows a different cooperation pattern between workers: hand-off, parallel fan-out, remote workers, etc. ## Setup @@ -9,7 +9,7 @@ From the repo root: ```bash uv sync --all-extras source .venv/bin/activate -cd examples/multi-task +cd examples/multi-worker ``` Copy the env template and fill in your API keys: @@ -22,7 +22,7 @@ cp env.example .env | Variable | Required by | | ------------------ | --------------------------------------- | -| `OPENAI_API_KEY` | LLM tasks | +| `OPENAI_API_KEY` | LLM workers | | `DEEPGRAM_API_KEY` | STT | | `CARTESIA_API_KEY` | TTS | | `DAILY_API_KEY` | Optional: only with `--transport daily` | @@ -33,7 +33,7 @@ Additional, example-specific variables are listed below. **[Local](#local)** (single process) -- [Handoff between LLM tasks](#handoff-between-llm-tasks) +- [Handoff between LLM workers](#handoff-between-llm-tasks) - [Parallel debate](#parallel-debate) - [Voice code assistant with Claude Agent SDK](#voice-code-assistant) - [Sensor controller](#sensor-controller) @@ -42,15 +42,15 @@ Additional, example-specific variables are listed below. - [Handoff via Redis](#handoff-via-redis) - [Handoff via PGMQ (Postgres)](#handoff-via-pgmq-postgres) -- [LLM task via WebSocket proxy](#llm-task-via-websocket-proxy) +- [LLM worker via WebSocket proxy](#llm-task-via-websocket-proxy) # Local -Examples where all tasks run in the same process on an `AsyncQueueBus`. +Examples where all workers run in the same process on an `AsyncQueueBus`. -## Handoff between LLM tasks +## Handoff between LLM workers -Two LLM tasks (greeter + support) that transfer control to each other during a voice conversation. A main task owns the transport pipeline and bridges frames to the bus. +Two LLM workers (greeter + support) that transfer control to each other during a voice conversation. A main worker owns the transport pipeline and bridges frames to the bus. ### Running @@ -68,12 +68,12 @@ uv run local-handoff/local-handoff-two-agents.py --transport daily ### Overview -- **[`local-handoff-two-agents.py`](local-handoff/local-handoff-two-agents.py)** — Two LLM tasks (greeter + support) that hand off via `activate_task(..., deactivate_self=True)`. The main task owns STT, TTS, transport, and a `BusBridgeProcessor`. -- **[`local-handoff-two-agents-tts.py`](local-handoff/local-handoff-two-agents-tts.py)** — Same shape, but each child task ships with its own `CartesiaTTSService` in a custom pipeline. The main task has no TTS — audio comes from whichever child is active over the bus. +- **[`local-handoff-two-agents.py`](local-handoff/local-handoff-two-agents.py)** — Two LLM workers (greeter + support) that hand off via `activate_worker(..., deactivate_self=True)`. The main worker owns STT, TTS, transport, and a `BusBridgeProcessor`. +- **[`local-handoff-two-agents-tts.py`](local-handoff/local-handoff-two-agents-tts.py)** — Same shape, but each child worker ships with its own `CartesiaTTSService` in a custom pipeline. The main worker has no TTS — audio comes from whichever child is active over the bus. ## Parallel debate -Parallel fan-out using `task.job_group(...)`. A voice bot takes a topic from the user, kicks off three worker tasks in parallel (advocate, critic, analyst), waits for all three to respond, and synthesizes a balanced answer. Each worker keeps its own LLM context across rounds. +Parallel fan-out using `worker.job_group(...)`. A voice bot takes a topic from the user, kicks off three workers in parallel (advocate, critic, analyst), waits for all three to respond, and synthesizes a balanced answer. Each worker keeps its own LLM context across rounds. ### Running @@ -92,13 +92,13 @@ uv run parallel-debate/parallel-debate.py --transport daily ### Architecture ``` -Main task (transport + LLM + `debate` tool) +Main worker (transport + LLM + `debate` tool) └── job_group(advocate, critic, analyst) - └── DebateWorker (LLMContextTask, one per role) + └── DebateWorker (LLMContextWorker, one per role) ``` -- **Main task**: transport (STT, TTS) + LLM moderator with a `debate` direct function that fans out via `task.job_group(...)`. -- **Debate workers**: `LLMContextTask`s spawned on the runner. Each keeps its own `LLMContext` across rounds and ships its completed turn back as a job response via the assistant-aggregator's `on_assistant_turn_stopped` event. +- **Main worker**: transport (STT, TTS) + LLM moderator with a `debate` direct function that fans out via `worker.job_group(...)`. +- **Debate workers**: `LLMContextWorker`s spawned on the runner. Each keeps its own `LLMContext` across rounds and ships its completed turn back as a job response via the assistant-aggregator's `on_assistant_turn_stopped` event. ## Voice code assistant @@ -140,16 +140,16 @@ uv run code-assistant/code-assistant.py --transport daily ### Architecture ``` -Main task (transport + LLM + `ask_code` tool) +Main worker (transport + LLM + `ask_code` tool) └── job → CodeWorker (Claude Agent SDK) ``` -- **`code-assistant.py`** — Main task: STT, LLM (with system prompt + `ask_code` direct function), TTS, and transport. The `ask_code` tool dispatches a job to the worker via `task.job("code_worker", payload=...)`. -- **`code_worker.py`** — `CodeWorker`: a bus-only `BaseTask` spawned on the runner. It accepts `@job`-style requests through the bus and runs them sequentially through a persistent Claude SDK session so follow-up questions share context. +- **`code-assistant.py`** — Main worker: STT, LLM (with system prompt + `ask_code` direct function), TTS, and transport. The `ask_code` tool dispatches a job to the worker via `worker.job("code_worker", payload=...)`. +- **`code_worker.py`** — `CodeWorker`: a bus-only `BaseWorker` spawned on the runner. It accepts `@job`-style requests through the bus and runs them sequentially through a persistent Claude SDK session so follow-up questions share context. ## Sensor controller -Two `PipelineTask`s side by side, communicating only over job RPC. A voice agent has a single `ask_controller(question)` tool that forwards every temperature-related request to a worker; the worker owns a simulated thermometer and its own tool-calling LLM that decides how to answer (read the current value, inspect rolling stats, change the target, change the response rate). The worker is a plain `PipelineTask` — it does not subclass `LLMTask` and is not bridged. +Two `PipelineWorker`s side by side, communicating only over job RPC. A voice agent has a single `ask_controller(question)` tool that forwards every temperature-related request to a worker; the worker owns a simulated thermometer and its own tool-calling LLM that decides how to answer (read the current value, inspect rolling stats, change the target, change the response rate). The worker is a plain `PipelineWorker` — it does not subclass `LLMWorker` and is not bridged. ### Running @@ -177,20 +177,20 @@ uv run sensor-controller/sensor-controller.py --transport daily ``` Voice agent (transport + STT + LLM + TTS, tool: ask_controller) - └── job → Controller (PipelineTask) + └── job → Controller (PipelineWorker) └── SensorReader -> SensorStats -> user_agg -> llm -> assistant_agg ``` -- **[`sensor-controller.py`](sensor-controller/sensor-controller.py)** — `build_sensor_controller()` returns a plain `PipelineTask`. Jobs arrive via `@worker.event_handler("on_job_request")`, the question is queued onto the worker LLM, and the LLM's reply is paired back to the job via the assistant aggregator's `on_assistant_turn_stopped` event. +- **[`sensor-controller.py`](sensor-controller/sensor-controller.py)** — `build_sensor_controller()` returns a plain `PipelineWorker`. Jobs arrive via `@worker.event_handler("on_job_request")`, the question is queued onto the worker LLM, and the LLM's reply is paired back to the job via the assistant aggregator's `on_assistant_turn_stopped` event. - **[`sensor.py`](sensor-controller/sensor.py)** — Two custom `FrameProcessor` subclasses: `SensorReader` runs an autonomous tick loop that emits a `SensorReadingFrame` each second (first-order lag toward target plus Gaussian noise; mutable target and response rate); `SensorStats` maintains rolling min/max/avg/trend. # Distributed -Examples where tasks run across separate processes or machines. +Examples where workers run across separate processes or machines. ## Handoff via Redis -Same two-task handoff as the local example, but each task runs as a separate process connected via Redis pub/sub. Requires `pip install pipecat-ai[redis]`. +Same two-worker handoff as the local example, but each worker runs as a separate process connected via Redis pub/sub. Requires `pip install pipecat-ai[redis]`. ### Quick start (single machine, local Redis) @@ -212,7 +212,7 @@ _Terminal 3_: start the support worker uv run distributed-handoff/redis-handoff/llm.py support ``` -_Terminal 4_: start the main transport task +_Terminal 4_: start the main transport worker ```bash uv run distributed-handoff/redis-handoff/main.py @@ -256,8 +256,8 @@ Machine A Redis Machine B +-------------+ ``` -- **[main.py](distributed-handoff/redis-handoff/main.py)** — Transport task: Daily/WebRTC, Deepgram STT, Cartesia TTS, and a `BusBridgeProcessor` over a `RedisBus`. -- **[llm.py](distributed-handoff/redis-handoff/llm.py)** — LLM worker: runs either `greeter` or `support` with OpenAI behind a bridged `LLMTask`. +- **[main.py](distributed-handoff/redis-handoff/main.py)** — Transport worker: Daily/WebRTC, Deepgram STT, Cartesia TTS, and a `BusBridgeProcessor` over a `RedisBus`. +- **[llm.py](distributed-handoff/redis-handoff/llm.py)** — LLM worker: runs either `greeter` or `support` with OpenAI behind a bridged `LLMWorker`. ## Handoff via PGMQ (Postgres) @@ -284,7 +284,7 @@ _Terminal 2_: start the support worker uv run distributed-handoff/pgmq-handoff/llm.py support --database-url $DATABASE_URL ``` -_Terminal 3_: start the main transport task +_Terminal 3_: start the main transport worker ```bash uv run distributed-handoff/pgmq-handoff/main.py --database-url $DATABASE_URL @@ -296,9 +296,9 @@ You can also set `DATABASE_URL` in `.env` and omit the `--database-url` flag. Same as the Redis handoff above; the `RedisBus` is replaced by a `PgmqBus`, and the "pub/sub channel" is a set of PGMQ queues on the shared Postgres instance. -## LLM task via WebSocket proxy +## LLM worker via WebSocket proxy -Runs an LLM task on a remote server, connected to the main transport task via a WebSocket proxy. No shared bus required — the proxy tasks forward bus messages point-to-point over the WebSocket. +Runs an LLM worker on a remote server, connected to the main transport worker via a WebSocket proxy. No shared bus required — the proxy workers forward bus messages point-to-point over the WebSocket. ### Quick start (single machine) @@ -308,7 +308,7 @@ _Terminal 1_: start the remote assistant server uv run remote-proxy-assistant/assistant.py ``` -_Terminal 2_: start the main transport task +_Terminal 2_: start the main transport worker ```bash uv run remote-proxy-assistant/main.py --remote-url ws://localhost:8765/ws @@ -335,7 +335,7 @@ uv run remote-proxy-assistant/main.py --remote-url ws://server-host:8765/ws ``` +-------------+ +-------------+ +-------------+ +-----------------+ | | | | | | | | - | Main task | | Proxy task | <~~~~~> | Proxy task | | Assistant task | + | Main worker | | Proxy worker | <~~~~~> | Proxy worker | | Assistant worker | | | | (client) | | (server) | | | +-------------+ +-------------+ +-------------+ +-----------------+ messages messages messages messages @@ -345,15 +345,15 @@ uv run remote-proxy-assistant/main.py --remote-url ws://server-host:8765/ws ═════════════════════════════════════ ═════════════════════════════════════════ ``` -- **[main.py](remote-proxy-assistant/main.py)** — Transport task with STT, TTS, and a `BusBridge`. Spawns a `WebSocketProxyClientTask` that connects to the remote server and forwards `BusFrameMessage`s. -- **[assistant.py](remote-proxy-assistant/assistant.py)** — FastAPI server. Each WebSocket connection spawns a `WebSocketProxyServerTask` plus a bridged `AcmeAssistant` LLM task on a per-session `PipelineRunner`. +- **[main.py](remote-proxy-assistant/main.py)** — Transport worker with STT, TTS, and a `BusBridge`. Spawns a `WebSocketProxyClientTask` that connects to the remote server and forwards `BusFrameMessage`s. +- **[assistant.py](remote-proxy-assistant/assistant.py)** — FastAPI server. Each WebSocket connection spawns a `WebSocketProxyServerTask` plus a bridged `AcmeAssistant` LLM worker on a per-session `PipelineRunner`. ### Security -The proxy tasks filter messages by task name: +The proxy workers filter messages by worker name: -- Only messages targeted at the remote task cross the WebSocket -- Only messages targeted at the local task are accepted from the WebSocket +- Only messages targeted at the remote worker cross the WebSocket +- Only messages targeted at the local worker are accepted from the WebSocket - Broadcast messages never cross the WebSocket Pass HTTP headers for authentication: @@ -362,8 +362,8 @@ Pass HTTP headers for authentication: proxy = WebSocketProxyClientTask( "proxy", url="wss://server-host:8765/ws", - remote_task_name="assistant", - local_task_name="acme", + remote_worker_name="assistant", + local_worker_name="acme", headers={"Authorization": "Bearer "}, ) ``` diff --git a/examples/multi-task/code-assistant/code-assistant.py b/examples/multi-worker/code-assistant/code-assistant.py similarity index 93% rename from examples/multi-task/code-assistant/code-assistant.py rename to examples/multi-worker/code-assistant/code-assistant.py index aaed286bc..1b1266cd1 100644 --- a/examples/multi-task/code-assistant/code-assistant.py +++ b/examples/multi-worker/code-assistant/code-assistant.py @@ -13,7 +13,7 @@ the filesystem using Read, Bash, Glob, and Grep tools. Architecture:: - Main task (transport + LLM + ``ask_code`` tool) + Main worker (transport + LLM + ``ask_code`` tool) └── job → CodeWorker (Claude Agent SDK) Requirements: @@ -36,7 +36,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMMessagesAppendFrame, LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -77,7 +77,7 @@ async def ask_code(params: FunctionCallParams, question: str): dependencies, or anything in the project. """ logger.info(f"Asking code worker: '{question}'") - async with params.pipeline_task.job("code_worker", payload={"question": question}) as job: + async with params.pipeline_worker.job("code_worker", payload={"question": question}) as job: await params.llm.queue_frame( LLMMessagesAppendFrame( messages=[{"role": "developer", "content": "Give me a moment."}], @@ -136,7 +136,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -154,15 +154,15 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): "content": "Greet the user and tell them you're a code assistant.", } ) - await task.queue_frame(LLMRunFrame()) + await worker.queue_frame(LLMRunFrame()) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info("Client disconnected") await runner.cancel() - await runner.spawn(CodeWorker("code_worker", project_path=PROJECT_PATH)) - await runner.spawn(task) + await runner.add_worker(CodeWorker("code_worker", project_path=PROJECT_PATH)) + await runner.add_worker(worker) await runner.run() diff --git a/examples/multi-task/code-assistant/code_worker.py b/examples/multi-worker/code-assistant/code_worker.py similarity index 94% rename from examples/multi-task/code-assistant/code_worker.py rename to examples/multi-worker/code-assistant/code_worker.py index 655043147..f585ee151 100644 --- a/examples/multi-task/code-assistant/code_worker.py +++ b/examples/multi-worker/code-assistant/code_worker.py @@ -11,7 +11,7 @@ import asyncio from loguru import logger from pipecat.bus import BusJobRequestMessage -from pipecat.pipeline.base_task import BaseTask +from pipecat.pipeline.base_worker import BaseWorker from pipecat.pipeline.job_context import JobStatus try: @@ -22,8 +22,8 @@ except ModuleNotFoundError as e: raise Exception(f"Missing module: {e}") -class CodeWorker(BaseTask): - """Bus-only task that answers code questions using Claude Agent SDK. +class CodeWorker(BaseWorker): + """Bus-only worker that answers code questions using Claude Agent SDK. Maintains a persistent Claude SDK session so follow-up questions share context. Questions are queued and processed sequentially. The @@ -35,7 +35,7 @@ class CodeWorker(BaseTask): """Initialize the CodeWorker. Args: - name: Unique task name. + name: Unique worker name. project_path: Filesystem path the Claude SDK should explore. """ super().__init__(name) @@ -60,12 +60,12 @@ class CodeWorker(BaseTask): ) async def start(self) -> None: - """Launch the Claude SDK worker loop alongside the standard task start.""" + """Launch the Claude SDK worker loop alongside the standard worker start.""" await super().start() self._worker_task = self.create_task(self._worker_loop(), "worker") async def stop(self) -> None: - """Cancel the worker loop before tearing down the task.""" + """Cancel the worker loop before tearing down the worker.""" if self._worker_task: await self.cancel_task(self._worker_task) self._worker_task = None diff --git a/examples/multi-task/distributed-handoff/pgmq-handoff/llm.py b/examples/multi-worker/distributed-handoff/pgmq-handoff/llm.py similarity index 87% rename from examples/multi-task/distributed-handoff/pgmq-handoff/llm.py rename to examples/multi-worker/distributed-handoff/pgmq-handoff/llm.py index b5995add4..ae4550a1c 100644 --- a/examples/multi-task/distributed-handoff/pgmq-handoff/llm.py +++ b/examples/multi-worker/distributed-handoff/pgmq-handoff/llm.py @@ -4,10 +4,10 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""LLM worker task — run on Machine B (or locally alongside ``main.py``). +"""LLM worker — run on Machine B (or locally alongside ``main.py``). -A standalone process that runs one LLM task (greeter or support) -attached to the same PGMQ-backed `TaskBus` as the main task. +A standalone process that runs one LLM worker (greeter or support) +attached to the same PGMQ-backed `WorkerBus` as the main worker. Multiple instances can run on different machines as long as they share a Postgres database with the PGMQ extension enabled. @@ -35,7 +35,7 @@ from pipecat.bus.network.pgmq import PgmqBus from pipecat.pipeline.runner import PipelineRunner from pipecat.services.llm_service import FunctionCallParams from pipecat.services.openai.llm import OpenAILLMService -from pipecat.tasks.llm import LLMTask, LLMTaskActivationArgs, tool +from pipecat.workers.llm import LLMWorker, LLMWorkerActivationArgs, tool load_dotenv(override=True) @@ -86,16 +86,16 @@ def pgmq_from_url(database_url: str, *, pool_size: int = 4) -> PGMQueue: ) -class AcmeLLMTask(LLMTask): - """LLM task for Acme Corp with transfer and end tools.""" +class AcmeLLMTask(LLMWorker): + """LLM worker for Acme Corp with transfer and end tools.""" def __init__(self, name: str, *, system_instruction: str, watch: list[str]): """Initialize the AcmeLLMTask. Args: - name: Unique task name (``"greeter"`` or ``"support"``). + name: Unique worker name (``"greeter"`` or ``"support"``). system_instruction: System prompt for this LLM role. - watch: Sibling task names this task will watch via the + watch: Sibling worker names this worker will watch via the registry so it knows when they become available for handoff. """ @@ -108,10 +108,10 @@ class AcmeLLMTask(LLMTask): self._watch = watch async def start(self) -> None: - """Register watches for sibling tasks once ready.""" + """Register watches for sibling workers once ready.""" await super().start() - for task_name in self._watch: - await self.watch_task(task_name) + for worker_name in self._watch: + await self.watch_worker(worker_name) @tool(cancel_on_interruption=False) async def transfer_to_agent(self, params: FunctionCallParams, agent: str, reason: str): @@ -122,9 +122,9 @@ class AcmeLLMTask(LLMTask): reason (str): Why the user is being transferred. """ logger.info(f"Task '{self.name}': transferring to '{agent}' ({reason})") - await self.activate_task( + await self.activate_worker( agent, - args=LLMTaskActivationArgs(messages=[{"role": "developer", "content": reason}]), + args=LLMWorkerActivationArgs(messages=[{"role": "developer", "content": reason}]), deactivate_self=True, result_callback=params.result_callback, ) @@ -145,7 +145,7 @@ class AcmeLLMTask(LLMTask): async def main_async() -> None: - parser = argparse.ArgumentParser(description="LLM worker task (greeter or support)") + parser = argparse.ArgumentParser(description="LLM worker (greeter or support)") parser.add_argument("worker", choices=list(WORKER_CONFIG), help="Which worker to run") parser.add_argument( "--database-url", diff --git a/examples/multi-task/distributed-handoff/pgmq-handoff/main.py b/examples/multi-worker/distributed-handoff/pgmq-handoff/main.py similarity index 90% rename from examples/multi-task/distributed-handoff/pgmq-handoff/main.py rename to examples/multi-worker/distributed-handoff/pgmq-handoff/main.py index 2cfb79be1..d38b79c13 100644 --- a/examples/multi-task/distributed-handoff/pgmq-handoff/main.py +++ b/examples/multi-worker/distributed-handoff/pgmq-handoff/main.py @@ -4,10 +4,10 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""Main transport task — run on Machine A. +"""Main transport worker — run on Machine A. Handles audio I/O (STT, TTS) and bridges frames to the bus. The LLM -worker tasks run as separate processes (possibly on different +workers run as separate processes (possibly on different machines) connected via PGMQ on a shared Postgres database (e.g. Supabase). @@ -35,20 +35,20 @@ from pipecat.bus import BusBridgeProcessor from pipecat.bus.network.pgmq import PgmqBus from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, LLMUserAggregatorParams, ) -from pipecat.registry.types import TaskReadyData +from pipecat.registry.types import WorkerReadyData from pipecat.runner.types import RunnerArguments from pipecat.runner.utils import create_transport from pipecat.services.cartesia.tts import CartesiaTTSService from pipecat.services.deepgram.stt import DeepgramSTTService -from pipecat.tasks.llm import LLMTaskActivationArgs from pipecat.transports.base_transport import BaseTransport, TransportParams from pipecat.transports.daily.transport import DailyParams +from pipecat.workers.llm import LLMWorkerActivationArgs load_dotenv(override=True) @@ -103,7 +103,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): bridge = BusBridgeProcessor( bus=runner.bus, - task_name=MAIN_NAME, + worker_name=MAIN_NAME, name=f"{MAIN_NAME}::BusBridge", ) @@ -119,7 +119,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, name=MAIN_NAME, params=PipelineParams( @@ -137,9 +137,9 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def maybe_activate(): if not (state["client_connected"] and state["greeter_ready"]): return - await task.activate_task( + await worker.activate_worker( "greeter", - args=LLMTaskActivationArgs( + args=LLMWorkerActivationArgs( messages=[ { "role": "developer", @@ -152,7 +152,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ), ) - async def on_greeter_ready(_data: TaskReadyData) -> None: + async def on_greeter_ready(_data: WorkerReadyData) -> None: state["greeter_ready"] = True await maybe_activate() @@ -167,9 +167,9 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info("Client disconnected") - await task.cancel() + await worker.cancel() - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): @@ -181,7 +181,7 @@ async def bot(runner_args: RunnerArguments): if __name__ == "__main__": from pipecat.runner.run import main - parser = argparse.ArgumentParser(description="Main transport task (PGMQ bus)") + parser = argparse.ArgumentParser(description="Main transport worker (PGMQ bus)") parser.add_argument( "--database-url", default=os.getenv("DATABASE_URL"), diff --git a/examples/multi-task/distributed-handoff/redis-handoff/llm.py b/examples/multi-worker/distributed-handoff/redis-handoff/llm.py similarity index 84% rename from examples/multi-task/distributed-handoff/redis-handoff/llm.py rename to examples/multi-worker/distributed-handoff/redis-handoff/llm.py index 594efde53..58ffde7b3 100644 --- a/examples/multi-task/distributed-handoff/redis-handoff/llm.py +++ b/examples/multi-worker/distributed-handoff/redis-handoff/llm.py @@ -4,10 +4,10 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""LLM worker task — run on Machine B (or locally alongside ``main.py``). +"""LLM worker — run on Machine B (or locally alongside ``main.py``). -A standalone process that runs one LLM task (greeter or support) -attached to the same Redis-backed `TaskBus` as the main task. +A standalone process that runs one LLM worker (greeter or support) +attached to the same Redis-backed `WorkerBus` as the main worker. Multiple instances can run on different machines. Usage:: @@ -32,7 +32,7 @@ from pipecat.bus.network.redis import RedisBus from pipecat.pipeline.runner import PipelineRunner from pipecat.services.llm_service import FunctionCallParams from pipecat.services.openai.llm import OpenAILLMService -from pipecat.tasks.llm import LLMTask, LLMTaskActivationArgs, tool +from pipecat.workers.llm import LLMWorker, LLMWorkerActivationArgs, tool load_dotenv(override=True) @@ -68,16 +68,16 @@ WORKER_CONFIG = { } -class AcmeLLMTask(LLMTask): - """LLM task for Acme Corp with transfer and end tools.""" +class AcmeLLMTask(LLMWorker): + """LLM worker for Acme Corp with transfer and end tools.""" def __init__(self, name: str, *, system_instruction: str, watch: list[str]): """Initialize the AcmeLLMTask. Args: - name: Unique task name (``"greeter"`` or ``"support"``). + name: Unique worker name (``"greeter"`` or ``"support"``). system_instruction: System prompt for this LLM role. - watch: Sibling task names this task will watch via the + watch: Sibling worker names this worker will watch via the registry so it knows when they become available for handoff. """ @@ -90,10 +90,10 @@ class AcmeLLMTask(LLMTask): self._watch = watch async def start(self) -> None: - """Register watches for sibling tasks once ready.""" + """Register watches for sibling workers once ready.""" await super().start() - for task_name in self._watch: - await self.watch_task(task_name) + for worker_name in self._watch: + await self.watch_worker(worker_name) @tool(cancel_on_interruption=False) async def transfer_to_agent(self, params: FunctionCallParams, agent: str, reason: str): @@ -104,9 +104,9 @@ class AcmeLLMTask(LLMTask): reason (str): Why the user is being transferred. """ logger.info(f"Task '{self.name}': transferring to '{agent}' ({reason})") - await self.activate_task( + await self.activate_worker( agent, - args=LLMTaskActivationArgs(messages=[{"role": "developer", "content": reason}]), + args=LLMWorkerActivationArgs(messages=[{"role": "developer", "content": reason}]), deactivate_self=True, result_callback=params.result_callback, ) @@ -127,7 +127,7 @@ class AcmeLLMTask(LLMTask): async def main_async() -> None: - parser = argparse.ArgumentParser(description="LLM worker task (greeter or support)") + parser = argparse.ArgumentParser(description="LLM worker (greeter or support)") parser.add_argument("worker", choices=list(WORKER_CONFIG), help="Which worker to run") parser.add_argument("--redis-url", default="redis://localhost:6379", help="Redis URL") parser.add_argument("--channel", default="pipecat:acme", help="Redis pub/sub channel") diff --git a/examples/multi-task/distributed-handoff/redis-handoff/main.py b/examples/multi-worker/distributed-handoff/redis-handoff/main.py similarity index 88% rename from examples/multi-task/distributed-handoff/redis-handoff/main.py rename to examples/multi-worker/distributed-handoff/redis-handoff/main.py index 6d513bf1a..d9a64d16f 100644 --- a/examples/multi-task/distributed-handoff/redis-handoff/main.py +++ b/examples/multi-worker/distributed-handoff/redis-handoff/main.py @@ -4,11 +4,11 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""Main transport task — run on Machine A. +"""Main transport worker — run on Machine A. Handles audio I/O (STT, TTS) and bridges frames to the bus. The LLM -worker tasks run as separate processes (possibly on different -machines) and connect to the same Redis-backed `TaskBus`. +workers run as separate processes (possibly on different +machines) and connect to the same Redis-backed `WorkerBus`. Usage:: @@ -32,20 +32,20 @@ from pipecat.bus import BusBridgeProcessor from pipecat.bus.network.redis import RedisBus from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, LLMUserAggregatorParams, ) -from pipecat.registry.types import TaskReadyData +from pipecat.registry.types import WorkerReadyData from pipecat.runner.types import RunnerArguments from pipecat.runner.utils import create_transport from pipecat.services.cartesia.tts import CartesiaTTSService from pipecat.services.deepgram.stt import DeepgramSTTService -from pipecat.tasks.llm import LLMTaskActivationArgs from pipecat.transports.base_transport import BaseTransport, TransportParams from pipecat.transports.daily.transport import DailyParams +from pipecat.workers.llm import LLMWorkerActivationArgs load_dotenv(override=True) @@ -84,7 +84,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): bridge = BusBridgeProcessor( bus=runner.bus, - task_name=MAIN_NAME, + worker_name=MAIN_NAME, name=f"{MAIN_NAME}::BusBridge", ) @@ -100,7 +100,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, name=MAIN_NAME, params=PipelineParams( @@ -118,9 +118,9 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def maybe_activate(): if not (state["client_connected"] and state["greeter_ready"]): return - await task.activate_task( + await worker.activate_worker( "greeter", - args=LLMTaskActivationArgs( + args=LLMWorkerActivationArgs( messages=[ { "role": "developer", @@ -133,7 +133,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ), ) - async def on_greeter_ready(_data: TaskReadyData) -> None: + async def on_greeter_ready(_data: WorkerReadyData) -> None: state["greeter_ready"] = True await maybe_activate() @@ -148,9 +148,9 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info("Client disconnected") - await task.cancel() + await worker.cancel() - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): @@ -162,7 +162,7 @@ async def bot(runner_args: RunnerArguments): if __name__ == "__main__": from pipecat.runner.run import main - parser = argparse.ArgumentParser(description="Main transport task (Redis bus)") + parser = argparse.ArgumentParser(description="Main transport worker (Redis bus)") parser.add_argument("--redis-url", default="redis://localhost:6379", help="Redis URL") parser.add_argument("--channel", default="pipecat:acme", help="Redis pub/sub channel") diff --git a/examples/multi-task/env.example b/examples/multi-worker/env.example similarity index 100% rename from examples/multi-task/env.example rename to examples/multi-worker/env.example diff --git a/examples/multi-task/local-handoff/local-handoff-two-agents-tts.py b/examples/multi-worker/local-handoff/local-handoff-two-agents-tts.py similarity index 87% rename from examples/multi-task/local-handoff/local-handoff-two-agents-tts.py rename to examples/multi-worker/local-handoff/local-handoff-two-agents-tts.py index 4871c2cf8..9d9951e7f 100644 --- a/examples/multi-task/local-handoff/local-handoff-two-agents-tts.py +++ b/examples/multi-worker/local-handoff/local-handoff-two-agents-tts.py @@ -4,20 +4,20 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""Two LLM tasks with per-task TTS voices. +"""Two LLM workers with per-worker TTS voices. -Same shape as ``local-handoff-two-agents.py``, but each child task -runs its own TTS with a distinct voice. The main task has no TTS — -audio comes from the child tasks via the bus and is played by the -main task's transport. Tasks announce the transfer ("let me connect +Same shape as ``local-handoff-two-agents.py``, but each child worker +runs its own TTS with a distinct voice. The main worker has no TTS — +audio comes from the child workers via the bus and is played by the +main worker's transport. Tasks announce the transfer ("let me connect you with...") before handing off. Architecture:: - Main task (no TTS): + Main worker (no TTS): transport.in → STT → user_agg → BusBridge → transport.out → assistant_agg - Child task (with TTS): + Child worker (with TTS): bridge_in → LLM → TTS → bridge_out Requirements: @@ -37,7 +37,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.bus import BusBridgeProcessor from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -49,9 +49,9 @@ from pipecat.services.cartesia.tts import CartesiaTTSService from pipecat.services.deepgram.stt import DeepgramSTTService from pipecat.services.llm_service import FunctionCallParams from pipecat.services.openai.llm import OpenAILLMService -from pipecat.tasks.llm import LLMTask, LLMTaskActivationArgs, tool from pipecat.transports.base_transport import BaseTransport, TransportParams from pipecat.transports.daily.transport import DailyParams +from pipecat.workers.llm import LLMWorker, LLMWorkerActivationArgs, tool load_dotenv(override=True) @@ -70,19 +70,19 @@ transport_params = { } -class AcmeTTSTask(LLMTask): - """Child task with its own LLM + TTS, bridged to the main task. +class AcmeTTSTask(LLMWorker): + """Child worker with its own LLM + TTS, bridged to the main worker. Each child wraps the standard ``Pipeline([llm])`` with an extra TTS processor so audio is produced locally by each child and - shipped to the main task over the bus. + shipped to the main worker over the bus. """ def __init__(self, name: str, *, llm: OpenAILLMService, voice_id: str): - """Initialize the child task. + """Initialize the child worker. Args: - name: Unique task name. + name: Unique worker name. llm: The LLM service for this child. voice_id: Cartesia voice id for this child's TTS. """ @@ -106,7 +106,7 @@ class AcmeTTSTask(LLMTask): reason (str): Why the user is being transferred. """ logger.info(f"Task '{self.name}': transferring to '{agent}' ({reason})") - await self.activate_task( + await self.activate_worker( agent, messages=[ { @@ -114,7 +114,7 @@ class AcmeTTSTask(LLMTask): "content": f"Tell the user about the transfer ({reason}).", } ], - args=LLMTaskActivationArgs( + args=LLMWorkerActivationArgs( messages=[{"role": "developer", "content": reason}], ), deactivate_self=True, @@ -198,12 +198,12 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): user_params=LLMUserAggregatorParams(vad_analyzer=SileroVADAnalyzer()), ) - # The main task has no TTS. Audio comes from the children over + # The main worker has no TTS. Audio comes from the children over # the bus; the main bridge tees user context out and pushes # incoming audio/text frames back into the local pipeline. bridge = BusBridgeProcessor( bus=runner.bus, - task_name=MAIN_NAME, + worker_name=MAIN_NAME, name=f"{MAIN_NAME}::BusBridge", ) @@ -218,7 +218,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, name=MAIN_NAME, params=PipelineParams( @@ -231,9 +231,9 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_connected") async def on_client_connected(transport, client): logger.info("Client connected") - await task.activate_task( + await worker.activate_worker( "greeter", - args=LLMTaskActivationArgs( + args=LLMWorkerActivationArgs( messages=[ { "role": "developer", @@ -251,9 +251,9 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): logger.info("Client disconnected") await runner.cancel() - await runner.spawn(build_greeter()) - await runner.spawn(build_support()) - await runner.spawn(task) + await runner.add_worker(build_greeter()) + await runner.add_worker(build_support()) + await runner.add_worker(worker) await runner.run() diff --git a/examples/multi-task/local-handoff/local-handoff-two-agents.py b/examples/multi-worker/local-handoff/local-handoff-two-agents.py similarity index 85% rename from examples/multi-task/local-handoff/local-handoff-two-agents.py rename to examples/multi-worker/local-handoff/local-handoff-two-agents.py index e77c28a17..eac7acf31 100644 --- a/examples/multi-task/local-handoff/local-handoff-two-agents.py +++ b/examples/multi-worker/local-handoff/local-handoff-two-agents.py @@ -4,14 +4,14 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""Two LLM tasks with a main task bridging transport to the bus. +"""Two LLM workers with a main worker bridging transport to the bus. -Demonstrates multi-task coordination: a main task handles transport I/O -(STT, TTS) and bridges frames to the bus. Two LLM tasks — a greeter and -a support task — each run their own LLM pipeline and hand off control +Demonstrates multi-worker coordination: a main worker handles transport I/O +(STT, TTS) and bridges frames to the bus. Two LLM workers — a greeter and +a support worker — each run their own LLM pipeline and hand off control between each other. -The user talks to one task at a time. Hand-offs are seamless — the LLM +The user talks to one worker at a time. Hand-offs are seamless — the LLM decides when to transfer based on its tools. Requirements: @@ -31,7 +31,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.bus import BusBridgeProcessor from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -43,9 +43,9 @@ from pipecat.services.cartesia.tts import CartesiaTTSService from pipecat.services.deepgram.stt import DeepgramSTTService from pipecat.services.llm_service import FunctionCallParams from pipecat.services.openai.llm import OpenAILLMService -from pipecat.tasks.llm import LLMTask, LLMTaskActivationArgs, tool from pipecat.transports.base_transport import BaseTransport, TransportParams from pipecat.transports.daily.transport import DailyParams +from pipecat.workers.llm import LLMWorker, LLMWorkerActivationArgs, tool load_dotenv(override=True) @@ -64,16 +64,16 @@ transport_params = { } -class AcmeLLMTask(LLMTask): - """LLM-only child task with transfer/end tools. +class AcmeLLMTask(LLMWorker): + """LLM-only child worker with transfer/end tools. - Receives user context from the main task via the bus, runs its LLM, - and ships generated text frames back. The main task's TTS turns the + Receives user context from the main worker via the bus, runs its LLM, + and ships generated text frames back. The main worker's TTS turns the text into audio. - Passing ``bridged=()`` tells :class:`PipelineTask` to wrap the LLM - pipeline with bus edge processors so frames flow between this task - and the main task automatically. + Passing ``bridged=()`` tells :class:`PipelineWorker` to wrap the LLM + pipeline with bus edge processors so frames flow between this worker + and the main worker automatically. """ @tool(cancel_on_interruption=False) @@ -85,9 +85,9 @@ class AcmeLLMTask(LLMTask): reason (str): Why the user is being transferred. """ logger.info(f"Task '{self.name}': transferring to '{agent}' ({reason})") - await self.activate_task( + await self.activate_worker( agent, - args=LLMTaskActivationArgs( + args=LLMWorkerActivationArgs( messages=[{"role": "developer", "content": reason}], ), deactivate_self=True, @@ -175,7 +175,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): # the TTS can speak it. bridge = BusBridgeProcessor( bus=runner.bus, - task_name=MAIN_NAME, + worker_name=MAIN_NAME, name=f"{MAIN_NAME}::BusBridge", ) @@ -191,7 +191,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, name=MAIN_NAME, params=PipelineParams( @@ -204,9 +204,9 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_connected") async def on_client_connected(transport, client): logger.info("Client connected") - await task.activate_task( + await worker.activate_worker( "greeter", - args=LLMTaskActivationArgs( + args=LLMWorkerActivationArgs( messages=[ { "role": "developer", @@ -224,9 +224,9 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): logger.info("Client disconnected") await runner.cancel() - await runner.spawn(build_greeter()) - await runner.spawn(build_support()) - await runner.spawn(task) + await runner.add_worker(build_greeter()) + await runner.add_worker(build_support()) + await runner.add_worker(worker) await runner.run() diff --git a/examples/multi-task/parallel-debate/parallel-debate.py b/examples/multi-worker/parallel-debate/parallel-debate.py similarity index 91% rename from examples/multi-task/parallel-debate/parallel-debate.py rename to examples/multi-worker/parallel-debate/parallel-debate.py index 7b51fecfe..1ce55ef7c 100644 --- a/examples/multi-task/parallel-debate/parallel-debate.py +++ b/examples/multi-worker/parallel-debate/parallel-debate.py @@ -7,16 +7,16 @@ """Parallel debate using job groups. A voice bot receives a topic from the user and fans out to three -worker tasks in parallel via ``task.job_group(...)``. Each worker +workers in parallel via ``worker.job_group(...)``. Each worker runs its own LLM context, so it remembers previous topics across debate rounds. The bot collects all three perspectives and the -main-task LLM synthesizes a balanced answer. +main-worker LLM synthesizes a balanced answer. Architecture:: - Main task (transport + LLM + ``debate`` tool) + Main worker (transport + LLM + ``debate`` tool) └── job_group(advocate, critic, analyst) - └── DebateWorker (LLMContextTask, one per role) + └── DebateWorker (LLMContextWorker, one per role) Requirements: @@ -37,7 +37,7 @@ from pipecat.bus import BusJobRequestMessage from pipecat.frames.frames import LLMMessagesAppendFrame, LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( AssistantTurnStoppedMessage, @@ -50,9 +50,9 @@ from pipecat.services.cartesia.tts import CartesiaTTSService from pipecat.services.deepgram.stt import DeepgramSTTService from pipecat.services.llm_service import FunctionCallParams from pipecat.services.openai.llm import OpenAILLMService -from pipecat.tasks.llm import LLMContextTask from pipecat.transports.base_transport import BaseTransport, TransportParams from pipecat.transports.daily.transport import DailyParams +from pipecat.workers.llm import LLMContextWorker load_dotenv(override=True) @@ -84,7 +84,7 @@ transport_params = { } -class DebateWorker(LLMContextTask): +class DebateWorker(LLMContextWorker): """Worker that generates a perspective using its own LLM context. Each worker keeps its own ``LLMContext`` so it remembers previous @@ -98,7 +98,7 @@ class DebateWorker(LLMContextTask): Args: role: One of ``"advocate"``, ``"critic"``, ``"analyst"`` — - used as the task name and selects the system prompt. + used as the worker name and selects the system prompt. """ llm = OpenAILLMService( api_key=os.environ["OPENAI_API_KEY"], @@ -136,7 +136,7 @@ async def debate(params: FunctionCallParams, topic: str): topic (str): The topic or question to debate. """ logger.info(f"Starting debate on '{topic}'") - async with params.pipeline_task.job_group( + async with params.pipeline_worker.job_group( *ROLE_PROMPTS, payload={"topic": topic}, timeout=30 ) as tg: pass @@ -189,7 +189,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -210,7 +210,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ), } ) - await task.queue_frame(LLMRunFrame()) + await worker.queue_frame(LLMRunFrame()) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): @@ -218,8 +218,8 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): await runner.cancel() for role in ROLE_PROMPTS: - await runner.spawn(DebateWorker(role)) - await runner.spawn(task) + await runner.add_worker(DebateWorker(role)) + await runner.add_worker(worker) await runner.run() diff --git a/examples/multi-task/remote-proxy-assistant/assistant.py b/examples/multi-worker/remote-proxy-assistant/assistant.py similarity index 89% rename from examples/multi-task/remote-proxy-assistant/assistant.py rename to examples/multi-worker/remote-proxy-assistant/assistant.py index 6f69e52c6..36520d4b3 100644 --- a/examples/multi-task/remote-proxy-assistant/assistant.py +++ b/examples/multi-worker/remote-proxy-assistant/assistant.py @@ -9,7 +9,7 @@ Runs a FastAPI server that accepts WebSocket connections from a ``main.py``-style client. Each connection spins up a `WebSocketProxyServerTask` bridging the socket to a local -`PipelineRunner` and an `LLMTask` that handles the conversation. +`PipelineRunner` and an `LLMWorker` that handles the conversation. Usage:: @@ -33,19 +33,19 @@ from pipecat.bus import BusFrameMessage from pipecat.pipeline.runner import PipelineRunner from pipecat.services.llm_service import FunctionCallParams from pipecat.services.openai.llm import OpenAILLMService -from pipecat.tasks.llm import LLMTask, tool -from pipecat.tasks.proxy.websocket import WebSocketProxyServerTask +from pipecat.workers.llm import LLMWorker, tool +from pipecat.workers.proxy.websocket import WebSocketProxyServerTask load_dotenv(override=True) app = FastAPI() -class AcmeAssistant(LLMTask): +class AcmeAssistant(LLMWorker): """Handles greetings, product questions, and conversation end.""" def __init__(self): - """Initialize the AcmeAssistant LLM task.""" + """Initialize the AcmeAssistant LLM worker.""" llm = OpenAILLMService( api_key=os.environ["OPENAI_API_KEY"], settings=OpenAILLMService.Settings( @@ -87,8 +87,8 @@ async def websocket_endpoint(websocket: WebSocket): proxy = WebSocketProxyServerTask( "gateway", websocket=websocket, - task_name="assistant", - remote_task_name="acme", + worker_name="assistant", + remote_worker_name="acme", forward_messages=(BusFrameMessage,), ) @@ -103,8 +103,8 @@ async def websocket_endpoint(websocket: WebSocket): assistant = AcmeAssistant() - await runner.spawn(proxy) - await runner.spawn(assistant) + await runner.add_worker(proxy) + await runner.add_worker(assistant) logger.info("Assistant server ready, waiting for activation") await runner.run() diff --git a/examples/multi-task/remote-proxy-assistant/main.py b/examples/multi-worker/remote-proxy-assistant/main.py similarity index 85% rename from examples/multi-task/remote-proxy-assistant/main.py rename to examples/multi-worker/remote-proxy-assistant/main.py index 299a85b19..4120e3b12 100644 --- a/examples/multi-task/remote-proxy-assistant/main.py +++ b/examples/multi-worker/remote-proxy-assistant/main.py @@ -4,7 +4,7 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""Main transport task with a WebSocket proxy to a remote LLM server. +"""Main transport worker with a WebSocket proxy to a remote LLM server. Handles audio I/O (STT, TTS) and bridges frames to the bus. A `WebSocketProxyClientTask` forwards bus messages to a remote LLM @@ -30,21 +30,21 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.bus import BusBridgeProcessor, BusFrameMessage from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, LLMUserAggregatorParams, ) -from pipecat.registry.types import TaskReadyData +from pipecat.registry.types import WorkerReadyData from pipecat.runner.types import RunnerArguments from pipecat.runner.utils import create_transport from pipecat.services.cartesia.tts import CartesiaTTSService from pipecat.services.deepgram.stt import DeepgramSTTService -from pipecat.tasks.llm import LLMTaskActivationArgs -from pipecat.tasks.proxy.websocket import WebSocketProxyClientTask from pipecat.transports.base_transport import BaseTransport, TransportParams from pipecat.transports.daily.transport import DailyParams +from pipecat.workers.llm import LLMWorkerActivationArgs +from pipecat.workers.proxy.websocket import WebSocketProxyClientTask load_dotenv(override=True) @@ -81,7 +81,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): bridge = BusBridgeProcessor( bus=runner.bus, - task_name=MAIN_NAME, + worker_name=MAIN_NAME, name=f"{MAIN_NAME}::BusBridge", ) @@ -97,7 +97,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, name=MAIN_NAME, params=PipelineParams( @@ -112,16 +112,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): proxy = WebSocketProxyClientTask( "proxy", url=runner_args.cli_args.remote_url, - local_task_name=MAIN_NAME, - remote_task_name="assistant", + local_worker_name=MAIN_NAME, + remote_worker_name="assistant", forward_messages=(BusFrameMessage,), ) - async def on_assistant_ready(_data: TaskReadyData) -> None: + async def on_assistant_ready(_data: WorkerReadyData) -> None: logger.info("Remote assistant ready, activating") - await task.activate_task( + await worker.activate_worker( "assistant", - args=LLMTaskActivationArgs( + args=LLMWorkerActivationArgs( messages=[ { "role": "developer", @@ -139,15 +139,15 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_connected") async def on_client_connected(transport, client): logger.info("Client connected, activating proxy") - await task.activate_task("proxy") + await worker.activate_worker("proxy") @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info("Client disconnected") await runner.cancel() - await runner.spawn(proxy) - await runner.spawn(task) + await runner.add_worker(proxy) + await runner.add_worker(worker) await runner.run() @@ -161,7 +161,7 @@ async def bot(runner_args: RunnerArguments): if __name__ == "__main__": from pipecat.runner.run import main - parser = argparse.ArgumentParser(description="Main transport task with WebSocket proxy") + parser = argparse.ArgumentParser(description="Main transport worker with WebSocket proxy") parser.add_argument( "--remote-url", default="ws://localhost:8765/ws", diff --git a/examples/multi-task/sensor-controller/sensor-controller.py b/examples/multi-worker/sensor-controller/sensor-controller.py similarity index 94% rename from examples/multi-task/sensor-controller/sensor-controller.py rename to examples/multi-worker/sensor-controller/sensor-controller.py index 61310d3a5..663729f73 100644 --- a/examples/multi-task/sensor-controller/sensor-controller.py +++ b/examples/multi-worker/sensor-controller/sensor-controller.py @@ -6,19 +6,19 @@ """Voice agent + sensor-controller worker, both as plain PipelineTasks. -Two ``PipelineTask`` instances run side by side: +Two ``PipelineWorker`` instances run side by side: - The **voice agent** is built inline in ``run_bot`` — a standard transport + STT + LLM + TTS pipeline. Its LLM has a single tool, ``ask_controller(question)``, which forwards the user's request to the controller over the bus and speaks back the response. - The **sensor controller** (``build_sensor_controller``) is a - ``PipelineTask`` whose pipeline runs a simulated temperature sensor + ``PipelineWorker`` whose pipeline runs a simulated temperature sensor (see ``sensor.py``) alongside its own LLM. The worker LLM has tool access to read the current reading, inspect rolling stats, and mutate the simulated sensor's target temperature and response rate. -The worker does **not** subclass ``LLMTask`` and is **not** bridged. +The worker does **not** subclass ``LLMWorker`` and is **not** bridged. The voice agent and the controller communicate exclusively through ``BusJobRequestMessage`` / ``BusJobResponseMessage``. The controller collects responses by listening to the assistant aggregator's @@ -59,7 +59,7 @@ from pipecat.bus import BusJobRequestMessage from pipecat.frames.frames import LLMMessagesAppendFrame, LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( AssistantTurnStoppedMessage, @@ -90,8 +90,8 @@ transport_params = { } -def build_sensor_controller() -> PipelineTask: - """Build the controller worker as a plain :class:`PipelineTask`. +def build_sensor_controller() -> PipelineWorker: + """Build the controller worker as a plain :class:`PipelineWorker`. The pipeline shape is:: @@ -188,7 +188,7 @@ def build_sensor_controller() -> PipelineTask: ] ) - worker = PipelineTask(pipeline, name="controller") + worker = PipelineWorker(pipeline, name="controller") # The controller handles one job at a time (the LLM pipeline can only # run one turn at a time). ``state["job_id"]`` pairs the in-flight @@ -247,7 +247,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): question (str): The user's question or instruction to forward to the controller. """ logger.info(f"Voice agent: forwarding to controller: '{question}'") - async with params.pipeline_task.job( + async with params.pipeline_worker.job( "controller", payload={"question": question}, timeout=30 ) as t: pass @@ -286,7 +286,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -309,15 +309,15 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ), } ) - await task.queue_frame(LLMRunFrame()) + await worker.queue_frame(LLMRunFrame()) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info("Client disconnected") await runner.cancel() - await runner.spawn(build_sensor_controller()) - await runner.spawn(task) + await runner.add_worker(build_sensor_controller()) + await runner.add_worker(worker) await runner.run() diff --git a/examples/multi-task/sensor-controller/sensor.py b/examples/multi-worker/sensor-controller/sensor.py similarity index 100% rename from examples/multi-task/sensor-controller/sensor.py rename to examples/multi-worker/sensor-controller/sensor.py diff --git a/examples/observability/observability-heartbeats.py b/examples/observability/observability-heartbeats.py index 87db2cd95..a7d901d04 100644 --- a/examples/observability/observability-heartbeats.py +++ b/examples/observability/observability-heartbeats.py @@ -12,7 +12,7 @@ from loguru import logger from pipecat.frames.frames import Frame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.frame_processor import FrameDirection, FrameProcessor logger.remove(0) @@ -32,11 +32,11 @@ async def main(): """ pipeline = Pipeline([NullProcessor()]) - task = PipelineTask(pipeline, params=PipelineParams(enable_heartbeats=True)) + worker = PipelineWorker(pipeline, params=PipelineParams(enable_heartbeats=True)) runner = PipelineRunner() - await runner.run(task) + await runner.run(worker) if __name__ == "__main__": diff --git a/examples/observability/observability-observer.py b/examples/observability/observability-observer.py index 4a1bbbbfa..6c718900a 100644 --- a/examples/observability/observability-observer.py +++ b/examples/observability/observability-observer.py @@ -25,7 +25,7 @@ from pipecat.observers.loggers.debug_log_observer import DebugLogObserver, Frame from pipecat.observers.loggers.llm_log_observer import LLMLogObserver from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -134,7 +134,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -161,16 +161,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/observability/observability-sentry-metrics.py b/examples/observability/observability-sentry-metrics.py index 9a8f8d553..79eecff8e 100644 --- a/examples/observability/observability-sentry-metrics.py +++ b/examples/observability/observability-sentry-metrics.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -98,7 +98,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -114,16 +114,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/persistent-context/persistent-context-anthropic.py b/examples/persistent-context/persistent-context-anthropic.py index cdddc9080..2cafb12c9 100644 --- a/examples/persistent-context/persistent-context-anthropic.py +++ b/examples/persistent-context/persistent-context-anthropic.py @@ -18,7 +18,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -211,7 +211,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -230,16 +230,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): "content": "Start the call by saying the word 'hello'. Say only that word.", } ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/persistent-context/persistent-context-aws-nova-sonic.py b/examples/persistent-context/persistent-context-aws-nova-sonic.py index 8a4b7ba47..591620d47 100644 --- a/examples/persistent-context/persistent-context-aws-nova-sonic.py +++ b/examples/persistent-context/persistent-context-aws-nova-sonic.py @@ -19,7 +19,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -254,7 +254,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -270,7 +270,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) # HACK: if using the older Nova Sonic (pre-2) model, you need this special way of # triggering the first assistant response. Note that this trigger requires a special # corresponding bit of text in the system instruction. @@ -279,11 +279,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/persistent-context/persistent-context-gemini.py b/examples/persistent-context/persistent-context-gemini.py index 2ae43bf87..e4429e8fd 100644 --- a/examples/persistent-context/persistent-context-gemini.py +++ b/examples/persistent-context/persistent-context-gemini.py @@ -18,7 +18,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, UserImageRequestFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -283,7 +283,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -307,16 +307,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): "content": f"Please introduce yourself to the user. Use '{client_id}' as the user ID during function calls.", } ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/persistent-context/persistent-context-grok-realtime.py b/examples/persistent-context/persistent-context-grok-realtime.py index e21dbf1c3..15c7c0ba8 100644 --- a/examples/persistent-context/persistent-context-grok-realtime.py +++ b/examples/persistent-context/persistent-context-grok-realtime.py @@ -29,7 +29,7 @@ from pipecat.adapters.schemas.tools_schema import ToolsSchema from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -215,7 +215,7 @@ Remember, your responses should be short - just one or two sentences usually.""" ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams(enable_metrics=True, enable_usage_metrics=True), idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, @@ -224,16 +224,16 @@ Remember, your responses should be short - just one or two sentences usually.""" @transport.event_handler("on_client_connected") async def on_client_connected(transport, client): logger.info("Client connected") - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info("Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/persistent-context/persistent-context-openai-realtime.py b/examples/persistent-context/persistent-context-openai-realtime.py index 067e1f73f..d8c92531e 100644 --- a/examples/persistent-context/persistent-context-openai-realtime.py +++ b/examples/persistent-context/persistent-context-openai-realtime.py @@ -19,7 +19,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -231,7 +231,7 @@ Remember, your responses should be short. Just one or two sentences, usually.""" ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -244,16 +244,16 @@ Remember, your responses should be short. Just one or two sentences, usually.""" async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/persistent-context/persistent-context-openai-responses-http.py b/examples/persistent-context/persistent-context-openai-responses-http.py index 362fd86f6..d15d8a761 100644 --- a/examples/persistent-context/persistent-context-openai-responses-http.py +++ b/examples/persistent-context/persistent-context-openai-responses-http.py @@ -18,7 +18,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -212,7 +212,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -225,16 +225,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/persistent-context/persistent-context-openai-responses.py b/examples/persistent-context/persistent-context-openai-responses.py index 9c3f33c94..6865dde60 100644 --- a/examples/persistent-context/persistent-context-openai-responses.py +++ b/examples/persistent-context/persistent-context-openai-responses.py @@ -18,7 +18,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -212,7 +212,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -225,16 +225,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/persistent-context/persistent-context-openai.py b/examples/persistent-context/persistent-context-openai.py index fa29ad5c2..0e4d52460 100644 --- a/examples/persistent-context/persistent-context-openai.py +++ b/examples/persistent-context/persistent-context-openai.py @@ -18,7 +18,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSSpeakFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -210,7 +210,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -223,16 +223,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/rag/rag-gemini-grounding-metadata.py b/examples/rag/rag-gemini-grounding-metadata.py index cddefe591..bab646eef 100644 --- a/examples/rag/rag-gemini-grounding-metadata.py +++ b/examples/rag/rag-gemini-grounding-metadata.py @@ -17,7 +17,7 @@ from pipecat.frames.frames import LLMRunFrame from pipecat.observers.base_observer import BaseObserver, FramePushed from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -138,7 +138,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -152,15 +152,15 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Start conversation - empty prompt to let LLM follow system instructions - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/rag/rag-gemini.py b/examples/rag/rag-gemini.py index 1567ad051..9247eb3f0 100644 --- a/examples/rag/rag-gemini.py +++ b/examples/rag/rag-gemini.py @@ -61,7 +61,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -235,7 +235,7 @@ Your response will be turned into speech so use only simple words and punctuatio assistant_aggregator, ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -251,15 +251,15 @@ Your response will be turned into speech so use only simple words and punctuatio context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/rag/rag-mem0.py b/examples/rag/rag-mem0.py index 1cbf97d14..9e385d0c3 100644 --- a/examples/rag/rag-mem0.py +++ b/examples/rag/rag-mem0.py @@ -46,7 +46,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -228,7 +228,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -247,15 +247,15 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message({"role": "developer", "content": greeting}) # Queue the context frame to start the conversation - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/realtime/realtime-aws-nova-sonic-async-tool.py b/examples/realtime/realtime-aws-nova-sonic-async-tool.py index 7a79fefeb..b3fcd7043 100644 --- a/examples/realtime/realtime-aws-nova-sonic-async-tool.py +++ b/examples/realtime/realtime-aws-nova-sonic-async-tool.py @@ -28,7 +28,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -146,7 +146,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -161,15 +161,15 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/realtime/realtime-aws-nova-sonic.py b/examples/realtime/realtime-aws-nova-sonic.py index 66be581e8..f5642f65e 100644 --- a/examples/realtime/realtime-aws-nova-sonic.py +++ b/examples/realtime/realtime-aws-nova-sonic.py @@ -19,7 +19,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( AssistantTurnStoppedMessage, @@ -165,8 +165,8 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - # Configure the pipeline task - task = PipelineTask( + # Configure the pipeline worker + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -183,7 +183,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) # HACK: if using the older Nova Sonic (pre-2) model, you need this special way of # triggering the first assistant response. Note that this trigger requires a special # corresponding bit of text in the system instruction. @@ -193,7 +193,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() @user_aggregator.event_handler("on_user_turn_stopped") async def on_user_turn_stopped(aggregator, strategy, message: UserTurnStoppedMessage): @@ -209,7 +209,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): # Run the pipeline runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/realtime/realtime-azure-async-tool.py b/examples/realtime/realtime-azure-async-tool.py index 46e561e0a..017003527 100644 --- a/examples/realtime/realtime-azure-async-tool.py +++ b/examples/realtime/realtime-azure-async-tool.py @@ -28,7 +28,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -157,7 +157,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -172,15 +172,15 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/realtime/realtime-azure.py b/examples/realtime/realtime-azure.py index c4ff80dcb..aa5b5ed80 100644 --- a/examples/realtime/realtime-azure.py +++ b/examples/realtime/realtime-azure.py @@ -17,7 +17,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -187,7 +187,7 @@ Remember, your responses should be short. Just one or two sentences, usually. Re ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -200,16 +200,16 @@ Remember, your responses should be short. Just one or two sentences, usually. Re async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/realtime/realtime-gemini-live-async-tool.py b/examples/realtime/realtime-gemini-live-async-tool.py index 23d9d8fa0..2a8a187e1 100644 --- a/examples/realtime/realtime-gemini-live-async-tool.py +++ b/examples/realtime/realtime-gemini-live-async-tool.py @@ -26,7 +26,7 @@ from pipecat.adapters.schemas.tools_schema import ToolsSchema from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import LLMContextAggregatorPair from pipecat.runner.types import RunnerArguments @@ -137,7 +137,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -152,15 +152,15 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/realtime/realtime-gemini-live-files-api.py b/examples/realtime/realtime-gemini-live-files-api.py index 99f35d52a..bcaa9bee9 100644 --- a/examples/realtime/realtime-gemini-live-files-api.py +++ b/examples/realtime/realtime-gemini-live-files-api.py @@ -13,7 +13,7 @@ from loguru import logger from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import LLMContextAggregatorPair from pipecat.runner.types import RunnerArguments @@ -171,8 +171,8 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - # Configure the pipeline task - task = PipelineTask( + # Configure the pipeline worker + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -186,17 +186,17 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation using standard context frame - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) # Handle client disconnection events @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() # Run the pipeline runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) # Clean up: delete the uploaded file and temporary file if file_info: diff --git a/examples/realtime/realtime-gemini-live-google-search.py b/examples/realtime/realtime-gemini-live-google-search.py index 6b132cef1..f58d168ea 100644 --- a/examples/realtime/realtime-gemini-live-google-search.py +++ b/examples/realtime/realtime-gemini-live-google-search.py @@ -13,7 +13,7 @@ from loguru import logger from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import LLMContextAggregatorPair from pipecat.runner.types import RunnerArguments @@ -96,7 +96,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -109,16 +109,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/realtime/realtime-gemini-live-graceful-end.py b/examples/realtime/realtime-gemini-live-graceful-end.py index d65414022..29adaddd0 100644 --- a/examples/realtime/realtime-gemini-live-graceful-end.py +++ b/examples/realtime/realtime-gemini-live-graceful-end.py @@ -15,7 +15,7 @@ from pipecat.adapters.schemas.tools_schema import AdapterType, ToolsSchema from pipecat.frames.frames import EndTaskFrame, LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import LLMContextAggregatorPair from pipecat.processors.frame_processor import FrameDirection @@ -160,7 +160,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -173,16 +173,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/realtime/realtime-gemini-live-grounding-metadata.py b/examples/realtime/realtime-gemini-live-grounding-metadata.py index e78d5cffa..dde140d9c 100644 --- a/examples/realtime/realtime-gemini-live-grounding-metadata.py +++ b/examples/realtime/realtime-gemini-live-grounding-metadata.py @@ -7,7 +7,7 @@ from pipecat.adapters.schemas.tools_schema import AdapterType, ToolsSchema from pipecat.frames.frames import Frame, LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineTask +from pipecat.pipeline.worker import PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import LLMContextAggregatorPair from pipecat.processors.frame_processor import FrameDirection, FrameProcessor @@ -128,7 +128,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, ) @@ -143,16 +143,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): "content": "Please introduce yourself and let me know that you can help with current information by searching the web. Ask me what current information I'd like to know about.", } ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/realtime/realtime-gemini-live-local-vad.py b/examples/realtime/realtime-gemini-live-local-vad.py index c7580f0c6..9829f2ac6 100644 --- a/examples/realtime/realtime-gemini-live-local-vad.py +++ b/examples/realtime/realtime-gemini-live-local-vad.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( AssistantTurnStoppedMessage, @@ -87,7 +87,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -100,12 +100,12 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() @user_aggregator.event_handler("on_user_turn_stopped") async def on_user_turn_stopped(aggregator, strategy, message: UserTurnStoppedMessage): @@ -121,7 +121,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/realtime/realtime-gemini-live-vertex.py b/examples/realtime/realtime-gemini-live-vertex.py index 2c0861006..b57de3204 100644 --- a/examples/realtime/realtime-gemini-live-vertex.py +++ b/examples/realtime/realtime-gemini-live-vertex.py @@ -16,7 +16,7 @@ from pipecat.adapters.schemas.tools_schema import ToolsSchema from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import LLMContextAggregatorPair from pipecat.runner.types import RunnerArguments @@ -136,7 +136,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -149,16 +149,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/realtime/realtime-gemini-live-video.py b/examples/realtime/realtime-gemini-live-video.py index 4319b534a..8051fa07d 100644 --- a/examples/realtime/realtime-gemini-live-video.py +++ b/examples/realtime/realtime-gemini-live-video.py @@ -14,7 +14,7 @@ from loguru import logger from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import LLMContextAggregatorPair from pipecat.runner.types import RunnerArguments @@ -76,7 +76,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -92,7 +92,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): await maybe_capture_participant_camera(transport, client, framerate=1) await maybe_capture_participant_screen(transport, client, framerate=1) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(3) logger.debug("Unpausing audio and video") llm.set_audio_input_paused(False) @@ -101,11 +101,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/realtime/realtime-gemini-live.py b/examples/realtime/realtime-gemini-live.py index 6751a16a7..4277f4388 100644 --- a/examples/realtime/realtime-gemini-live.py +++ b/examples/realtime/realtime-gemini-live.py @@ -16,7 +16,7 @@ from pipecat.adapters.schemas.tools_schema import AdapterType, ToolsSchema from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( AssistantTurnStoppedMessage, @@ -143,7 +143,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -159,12 +159,12 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() @user_aggregator.event_handler("on_user_turn_stopped") async def on_user_turn_stopped(aggregator, strategy, message: UserTurnStoppedMessage): @@ -180,7 +180,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/realtime/realtime-grok-async-tool.py b/examples/realtime/realtime-grok-async-tool.py index c54668fbb..db0a70877 100644 --- a/examples/realtime/realtime-grok-async-tool.py +++ b/examples/realtime/realtime-grok-async-tool.py @@ -27,7 +27,7 @@ from pipecat.adapters.schemas.tools_schema import ToolsSchema from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import LLMContextAggregatorPair from pipecat.runner.types import RunnerArguments @@ -141,7 +141,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -156,15 +156,15 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/realtime/realtime-grok.py b/examples/realtime/realtime-grok.py index 1e122865a..52f71eda5 100644 --- a/examples/realtime/realtime-grok.py +++ b/examples/realtime/realtime-grok.py @@ -42,7 +42,7 @@ from pipecat.observers.loggers.transcription_log_observer import ( ) from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( AssistantTurnStoppedMessage, @@ -227,7 +227,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -241,12 +241,12 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info("Client connected") # Kick off the conversation - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info("Client disconnected") - await task.cancel() + await worker.cancel() # Log transcript updates @user_aggregator.event_handler("on_user_turn_stopped") @@ -263,7 +263,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/realtime/realtime-inworld.py b/examples/realtime/realtime-inworld.py index fdc1712ce..4546c21ac 100644 --- a/examples/realtime/realtime-inworld.py +++ b/examples/realtime/realtime-inworld.py @@ -42,7 +42,7 @@ from pipecat.observers.loggers.transcription_log_observer import ( ) from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( AssistantTurnStoppedMessage, @@ -162,7 +162,7 @@ Always be helpful and proactive in offering assistance.""", ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -175,12 +175,12 @@ Always be helpful and proactive in offering assistance.""", @transport.event_handler("on_client_connected") async def on_client_connected(transport, client): logger.info("Client connected") - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info("Client disconnected") - await task.cancel() + await worker.cancel() @user_aggregator.event_handler("on_user_turn_stopped") async def on_user_turn_stopped(aggregator, strategy, message: UserTurnStoppedMessage): @@ -194,7 +194,7 @@ Always be helpful and proactive in offering assistance.""", runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/realtime/realtime-openai-async-tool.py b/examples/realtime/realtime-openai-async-tool.py index 49c23e038..0c458d134 100644 --- a/examples/realtime/realtime-openai-async-tool.py +++ b/examples/realtime/realtime-openai-async-tool.py @@ -28,7 +28,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -160,7 +160,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -175,15 +175,15 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/realtime/realtime-openai-live-video.py b/examples/realtime/realtime-openai-live-video.py index b35aa2648..67eed92cd 100644 --- a/examples/realtime/realtime-openai-live-video.py +++ b/examples/realtime/realtime-openai-live-video.py @@ -15,7 +15,7 @@ from pipecat.frames.frames import LLMRunFrame from pipecat.observers.loggers.transcription_log_observer import TranscriptionLogObserver from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -119,7 +119,7 @@ Remember, your responses should be short. Just one or two sentences, usually. Re ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -136,16 +136,16 @@ Remember, your responses should be short. Just one or two sentences, usually. Re await maybe_capture_participant_camera(transport, client, framerate=1) await maybe_capture_participant_screen(transport, client, framerate=1) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/realtime/realtime-openai-text.py b/examples/realtime/realtime-openai-text.py index f36a3c773..a79282e7a 100644 --- a/examples/realtime/realtime-openai-text.py +++ b/examples/realtime/realtime-openai-text.py @@ -17,7 +17,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -191,7 +191,7 @@ Remember, your responses should be short. Just one or two sentences, usually. Re ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -204,16 +204,16 @@ Remember, your responses should be short. Just one or two sentences, usually. Re async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/realtime/realtime-openai.py b/examples/realtime/realtime-openai.py index 0ec913add..359c8acb2 100644 --- a/examples/realtime/realtime-openai.py +++ b/examples/realtime/realtime-openai.py @@ -19,7 +19,7 @@ from pipecat.frames.frames import LLMRunFrame, LLMSetToolsFrame from pipecat.observers.loggers.transcription_log_observer import TranscriptionLogObserver from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( AssistantTurnStoppedMessage, @@ -200,7 +200,7 @@ Remember, your responses should be short. Just one or two sentences, usually. Re ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -214,27 +214,27 @@ Remember, your responses should be short. Just one or two sentences, usually. Re async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) # Add a new tool at runtime after a delay. await asyncio.sleep(15) new_tools = ToolsSchema( standard_tools=[weather_function, restaurant_function, get_news_function] ) - await task.queue_frames([LLMSetToolsFrame(tools=new_tools)]) + await worker.queue_frames([LLMSetToolsFrame(tools=new_tools)]) # Alternative pattern, useful if you're changing other session properties, too. # (Though note that tools in your LLMContext take precedence over those # in session properties, so if you have context-provided tools, prefer # LLMSetToolsFrame instead, as it updates your context. Ditto for # updating system instructions: send an LLMMessagesUpdateFrame with # context messages updated with your new desired system message.) - # await task.queue_frames( + # await worker.queue_frames( # [LLMUpdateSettingsFrame(settings=SessionProperties(tools=new_tools).model_dump())] # ) # Reasoning effort can be changed at runtime too. Only # reasoning-capable Realtime models (e.g. gpt-realtime-2) support this. - # await task.queue_frames( + # await worker.queue_frames( # [ # LLMUpdateSettingsFrame( # delta=OpenAIRealtimeLLMService.Settings( @@ -249,7 +249,7 @@ Remember, your responses should be short. Just one or two sentences, usually. Re @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() # Log transcript updates @user_aggregator.event_handler("on_user_turn_stopped") @@ -266,7 +266,7 @@ Remember, your responses should be short. Just one or two sentences, usually. Re runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/realtime/realtime-ultravox-async-tool.py b/examples/realtime/realtime-ultravox-async-tool.py index 449844d5a..3c46f21c6 100644 --- a/examples/realtime/realtime-ultravox-async-tool.py +++ b/examples/realtime/realtime-ultravox-async-tool.py @@ -29,7 +29,7 @@ from pipecat.adapters.schemas.tools_schema import ToolsSchema from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -152,7 +152,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -168,10 +168,10 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/realtime/realtime-ultravox-text.py b/examples/realtime/realtime-ultravox-text.py index a144af919..2cc857cdb 100644 --- a/examples/realtime/realtime-ultravox-text.py +++ b/examples/realtime/realtime-ultravox-text.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.audio.vad.vad_analyzer import VADParams from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( AssistantTurnStoppedMessage, @@ -213,8 +213,8 @@ There is also a secret menu that changes daily. If the user asks about it, use t ] ) - # Configure the pipeline task - task = PipelineTask( + # Configure the pipeline worker + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -232,7 +232,7 @@ There is also a secret menu that changes daily. If the user asks about it, use t @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() @user_aggregator.event_handler("on_user_turn_stopped") async def on_user_turn_stopped(aggregator, strategy, message: UserTurnStoppedMessage): @@ -248,7 +248,7 @@ There is also a secret menu that changes daily. If the user asks about it, use t # Run the pipeline runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/realtime/realtime-ultravox.py b/examples/realtime/realtime-ultravox.py index ed46aba2f..448b83b81 100644 --- a/examples/realtime/realtime-ultravox.py +++ b/examples/realtime/realtime-ultravox.py @@ -15,7 +15,7 @@ from pipecat.adapters.schemas.tools_schema import ToolsSchema from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( AssistantTurnStoppedMessage, @@ -203,8 +203,8 @@ There is also a secret menu that changes daily. If the user asks about it, use t ] ) - # Configure the pipeline task - task = PipelineTask( + # Configure the pipeline worker + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -222,7 +222,7 @@ There is also a secret menu that changes daily. If the user asks about it, use t @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() @user_aggregator.event_handler("on_user_turn_stopped") async def on_user_turn_stopped(aggregator, strategy, message: UserTurnStoppedMessage): @@ -238,7 +238,7 @@ There is also a secret menu that changes daily. If the user asks about it, use t # Run the pipeline runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/thinking/thinking-anthropic.py b/examples/thinking/thinking-anthropic.py index fe64aa3f3..131e2599f 100644 --- a/examples/thinking/thinking-anthropic.py +++ b/examples/thinking/thinking-anthropic.py @@ -13,7 +13,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( AssistantThoughtMessage, @@ -90,7 +90,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -114,12 +114,12 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): # # "content": "Are there an infinite number of prime numbers such that n mod 4 == 3?" # } # ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() @assistant_aggregator.event_handler("on_assistant_thought") async def on_assistant_thought(aggregator, message: AssistantThoughtMessage): @@ -127,7 +127,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/thinking/thinking-functions-anthropic.py b/examples/thinking/thinking-functions-anthropic.py index f69b271fb..e878a4c62 100644 --- a/examples/thinking/thinking-functions-anthropic.py +++ b/examples/thinking/thinking-functions-anthropic.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( AssistantThoughtMessage, @@ -116,7 +116,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -139,12 +139,12 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): # "content": "Check the status of flight AA100 and, if it's delayed, book me a taxi 2 hours before its departure time.", # } # ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() @assistant_aggregator.event_handler("on_assistant_thought") async def on_assistant_thought(aggregator, message: AssistantThoughtMessage): @@ -152,7 +152,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/thinking/thinking-functions-google.py b/examples/thinking/thinking-functions-google.py index 680f2c70b..cfa19d8c2 100644 --- a/examples/thinking/thinking-functions-google.py +++ b/examples/thinking/thinking-functions-google.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( AssistantThoughtMessage, @@ -117,7 +117,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -140,12 +140,12 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): # "content": "Check the status of flight AA100 and, if it's delayed, book me a taxi 2 hours before its departure time.", # } # ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() @assistant_aggregator.event_handler("on_assistant_thought") async def on_assistant_thought(aggregator, message: AssistantThoughtMessage): @@ -153,7 +153,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/thinking/thinking-google.py b/examples/thinking/thinking-google.py index 12de4a313..db5507a98 100644 --- a/examples/thinking/thinking-google.py +++ b/examples/thinking/thinking-google.py @@ -13,7 +13,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( AssistantThoughtMessage, @@ -91,7 +91,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -116,12 +116,12 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): # # "content": "Are there an infinite number of prime numbers such that n mod 4 == 3?" # } # ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() @assistant_aggregator.event_handler("on_assistant_thought") async def on_assistant_thought(aggregator, message: AssistantThoughtMessage): @@ -129,7 +129,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/transcription/transcription-assemblyai.py b/examples/transcription/transcription-assemblyai.py index f9db2c85e..b7c40a398 100644 --- a/examples/transcription/transcription-assemblyai.py +++ b/examples/transcription/transcription-assemblyai.py @@ -12,7 +12,7 @@ from loguru import logger from pipecat.frames.frames import Frame, TranscriptionFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineTask +from pipecat.pipeline.worker import PipelineWorker from pipecat.processors.frame_processor import FrameDirection, FrameProcessor from pipecat.runner.types import RunnerArguments from pipecat.runner.utils import create_transport @@ -58,7 +58,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): pipeline = Pipeline([transport.input(), stt, tl]) - task = PipelineTask( + worker = PipelineWorker( pipeline, idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, ) @@ -66,11 +66,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/transcription/transcription-azure.py b/examples/transcription/transcription-azure.py index 1a551f745..d660f1056 100644 --- a/examples/transcription/transcription-azure.py +++ b/examples/transcription/transcription-azure.py @@ -13,7 +13,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import Frame, TranscriptionFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineTask +from pipecat.pipeline.worker import PipelineWorker from pipecat.processors.audio.vad_processor import VADProcessor from pipecat.processors.frame_processor import FrameDirection, FrameProcessor from pipecat.runner.types import RunnerArguments @@ -63,7 +63,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): pipeline = Pipeline([transport.input(), vad_processor, stt, tl]) - task = PipelineTask( + worker = PipelineWorker( pipeline, idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, ) @@ -71,11 +71,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/transcription/transcription-cartesia.py b/examples/transcription/transcription-cartesia.py index f86e5fa37..08a7baff9 100644 --- a/examples/transcription/transcription-cartesia.py +++ b/examples/transcription/transcription-cartesia.py @@ -12,7 +12,7 @@ from loguru import logger from pipecat.frames.frames import Frame, TranscriptionFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineTask +from pipecat.pipeline.worker import PipelineWorker from pipecat.processors.frame_processor import FrameDirection, FrameProcessor from pipecat.runner.types import RunnerArguments from pipecat.runner.utils import create_transport @@ -53,7 +53,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): pipeline = Pipeline([transport.input(), stt, tl]) - task = PipelineTask( + worker = PipelineWorker( pipeline, idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, ) @@ -61,11 +61,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/transcription/transcription-deepgram.py b/examples/transcription/transcription-deepgram.py index 92fe076e3..3ff9ecd5b 100644 --- a/examples/transcription/transcription-deepgram.py +++ b/examples/transcription/transcription-deepgram.py @@ -12,7 +12,7 @@ from loguru import logger from pipecat.frames.frames import Frame, TranscriptionFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineTask +from pipecat.pipeline.worker import PipelineWorker from pipecat.processors.frame_processor import FrameDirection, FrameProcessor from pipecat.runner.types import RunnerArguments from pipecat.runner.utils import create_transport @@ -58,7 +58,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): pipeline = Pipeline([transport.input(), stt, tl]) - task = PipelineTask( + worker = PipelineWorker( pipeline, idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, ) @@ -66,11 +66,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/transcription/transcription-elevenlabs.py b/examples/transcription/transcription-elevenlabs.py index 548a12de2..a35a26d88 100644 --- a/examples/transcription/transcription-elevenlabs.py +++ b/examples/transcription/transcription-elevenlabs.py @@ -13,7 +13,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import Frame, TranscriptionFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineTask +from pipecat.pipeline.worker import PipelineWorker from pipecat.processors.audio.vad_processor import VADProcessor from pipecat.processors.frame_processor import FrameDirection, FrameProcessor from pipecat.runner.types import RunnerArguments @@ -56,7 +56,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): pipeline = Pipeline([transport.input(), vad_processor, stt, tl]) - task = PipelineTask( + worker = PipelineWorker( pipeline, idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, ) @@ -64,11 +64,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/transcription/transcription-gladia-translation.py b/examples/transcription/transcription-gladia-translation.py index 477c73b23..ed463e610 100644 --- a/examples/transcription/transcription-gladia-translation.py +++ b/examples/transcription/transcription-gladia-translation.py @@ -12,7 +12,7 @@ from loguru import logger from pipecat.frames.frames import Frame, TranscriptionFrame, TranslationFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineTask +from pipecat.pipeline.worker import PipelineWorker from pipecat.processors.frame_processor import FrameDirection, FrameProcessor from pipecat.runner.types import RunnerArguments from pipecat.runner.utils import create_transport @@ -80,7 +80,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): pipeline = Pipeline([transport.input(), stt, tl]) - task = PipelineTask( + worker = PipelineWorker( pipeline, idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, ) @@ -88,11 +88,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/transcription/transcription-gladia.py b/examples/transcription/transcription-gladia.py index cd1152972..f36fa00a4 100644 --- a/examples/transcription/transcription-gladia.py +++ b/examples/transcription/transcription-gladia.py @@ -12,7 +12,7 @@ from loguru import logger from pipecat.frames.frames import Frame, TranscriptionFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineTask +from pipecat.pipeline.worker import PipelineWorker from pipecat.processors.frame_processor import FrameDirection, FrameProcessor from pipecat.runner.types import RunnerArguments from pipecat.runner.utils import create_transport @@ -64,7 +64,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): pipeline = Pipeline([transport.input(), stt, tl]) - task = PipelineTask( + worker = PipelineWorker( pipeline, idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, ) @@ -72,11 +72,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/transcription/transcription-google-llm.py b/examples/transcription/transcription-google-llm.py index 909711ecd..d99a6435d 100644 --- a/examples/transcription/transcription-google-llm.py +++ b/examples/transcription/transcription-google-llm.py @@ -26,7 +26,7 @@ from pipecat.frames.frames import ( from pipecat.pipeline.parallel_pipeline import ParallelPipeline from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -355,7 +355,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -368,16 +368,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/transcription/transcription-gradium.py b/examples/transcription/transcription-gradium.py index 0fad1630b..61d655e68 100644 --- a/examples/transcription/transcription-gradium.py +++ b/examples/transcription/transcription-gradium.py @@ -12,7 +12,7 @@ from loguru import logger from pipecat.frames.frames import Frame, TranscriptionFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineTask +from pipecat.pipeline.worker import PipelineWorker from pipecat.processors.frame_processor import FrameDirection, FrameProcessor from pipecat.runner.types import RunnerArguments from pipecat.runner.utils import create_transport @@ -61,7 +61,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): pipeline = Pipeline([transport.input(), stt, tl]) - task = PipelineTask( + worker = PipelineWorker( pipeline, idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, ) @@ -69,11 +69,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/transcription/transcription-mistral.py b/examples/transcription/transcription-mistral.py index fa471d2e6..db957e7ca 100644 --- a/examples/transcription/transcription-mistral.py +++ b/examples/transcription/transcription-mistral.py @@ -13,7 +13,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import Frame, TranscriptionFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.audio.vad_processor import VADProcessor from pipecat.processors.frame_processor import FrameDirection, FrameProcessor from pipecat.runner.types import RunnerArguments @@ -62,7 +62,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): pipeline = Pipeline([transport.input(), vad_processor, stt, tl]) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -74,11 +74,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/transcription/transcription-openai.py b/examples/transcription/transcription-openai.py index 47228ce8b..89c2f67c5 100644 --- a/examples/transcription/transcription-openai.py +++ b/examples/transcription/transcription-openai.py @@ -13,7 +13,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import Frame, TranscriptionFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineTask +from pipecat.pipeline.worker import PipelineWorker from pipecat.processors.audio.vad_processor import VADProcessor from pipecat.processors.frame_processor import FrameDirection, FrameProcessor from pipecat.runner.types import RunnerArguments @@ -56,7 +56,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): pipeline = Pipeline([transport.input(), vad_processor, stt, tl]) - task = PipelineTask( + worker = PipelineWorker( pipeline, idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, ) @@ -64,11 +64,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/transcription/transcription-soniox.py b/examples/transcription/transcription-soniox.py index b912fa04c..865b7ff61 100644 --- a/examples/transcription/transcription-soniox.py +++ b/examples/transcription/transcription-soniox.py @@ -13,7 +13,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import Frame, TranscriptionFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineTask +from pipecat.pipeline.worker import PipelineWorker from pipecat.processors.audio.vad_processor import VADProcessor from pipecat.processors.frame_processor import FrameDirection, FrameProcessor from pipecat.runner.types import RunnerArguments @@ -62,7 +62,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): pipeline = Pipeline([transport.input(), vad_processor, stt, tl]) - task = PipelineTask( + worker = PipelineWorker( pipeline, idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, ) @@ -70,11 +70,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/transcription/transcription-speechmatics.py b/examples/transcription/transcription-speechmatics.py index 2134c8c97..99ff94abf 100644 --- a/examples/transcription/transcription-speechmatics.py +++ b/examples/transcription/transcription-speechmatics.py @@ -12,7 +12,7 @@ from loguru import logger from pipecat.frames.frames import Frame, TranscriptionFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineTask +from pipecat.pipeline.worker import PipelineWorker from pipecat.processors.frame_processor import FrameDirection, FrameProcessor from pipecat.runner.types import RunnerArguments from pipecat.runner.utils import create_transport @@ -75,7 +75,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): pipeline = Pipeline([transport.input(), stt, tl]) - task = PipelineTask( + worker = PipelineWorker( pipeline, idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, ) @@ -83,11 +83,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/transcription/transcription-whisper-local.py b/examples/transcription/transcription-whisper-local.py index 0882542fc..62a9dbe8f 100644 --- a/examples/transcription/transcription-whisper-local.py +++ b/examples/transcription/transcription-whisper-local.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import Frame, TranscriptionFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineTask +from pipecat.pipeline.worker import PipelineWorker from pipecat.processors.audio.vad_processor import VADProcessor from pipecat.processors.frame_processor import FrameDirection, FrameProcessor from pipecat.services.whisper.stt import WhisperSTTService @@ -51,11 +51,11 @@ async def main(): pipeline = Pipeline([transport.input(), vad_processor, stt, tl]) - task = PipelineTask(pipeline) + worker = PipelineWorker(pipeline) runner = PipelineRunner(handle_sigint=False if sys.platform == "win32" else True) - await runner.run(task) + await runner.run(worker) if __name__ == "__main__": diff --git a/examples/transcription/transcription-whisper-mlx.py b/examples/transcription/transcription-whisper-mlx.py index af7d2d79e..bed2f09af 100644 --- a/examples/transcription/transcription-whisper-mlx.py +++ b/examples/transcription/transcription-whisper-mlx.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.vad_analyzer import VADParams from pipecat.frames.frames import Frame, TranscriptionFrame, UserStoppedSpeakingFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.audio.vad_processor import VADProcessor from pipecat.processors.frame_processor import FrameDirection, FrameProcessor from pipecat.runner.types import RunnerArguments @@ -88,7 +88,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): pipeline = Pipeline([transport.input(), vad_processor, stt, tl]) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -100,11 +100,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/transcription/transcription-whisper.py b/examples/transcription/transcription-whisper.py index f61cec132..3e5d12e9c 100644 --- a/examples/transcription/transcription-whisper.py +++ b/examples/transcription/transcription-whisper.py @@ -12,7 +12,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import Frame, TranscriptionFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineTask +from pipecat.pipeline.worker import PipelineWorker from pipecat.processors.audio.vad_processor import VADProcessor from pipecat.processors.frame_processor import FrameDirection, FrameProcessor from pipecat.runner.types import RunnerArguments @@ -61,7 +61,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): pipeline = Pipeline([transport.input(), vad_processor, stt, tl]) - task = PipelineTask( + worker = PipelineWorker( pipeline, idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, ) @@ -69,11 +69,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/transcription/transcription-xai.py b/examples/transcription/transcription-xai.py index 0cc667f9a..8a994f376 100644 --- a/examples/transcription/transcription-xai.py +++ b/examples/transcription/transcription-xai.py @@ -12,7 +12,7 @@ from loguru import logger from pipecat.frames.frames import Frame, TranscriptionFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineTask +from pipecat.pipeline.worker import PipelineWorker from pipecat.processors.frame_processor import FrameDirection, FrameProcessor from pipecat.runner.types import RunnerArguments from pipecat.runner.utils import create_transport @@ -59,7 +59,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): pipeline = Pipeline([transport.input(), stt, tl]) - task = PipelineTask( + worker = PipelineWorker( pipeline, idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, ) @@ -67,11 +67,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/transports/transports-daily.py b/examples/transports/transports-daily.py index 09deda2dd..f66b7fbbf 100644 --- a/examples/transports/transports-daily.py +++ b/examples/transports/transports-daily.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -79,7 +79,7 @@ async def main(): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -94,15 +94,15 @@ async def main(): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_participant_left") async def on_participant_left(transport, participant, reason): - await task.cancel() + await worker.cancel() runner = PipelineRunner() - await runner.run(task) + await runner.run(worker) if __name__ == "__main__": diff --git a/examples/transports/transports-livekit.py b/examples/transports/transports-livekit.py index 8bb147c04..251b00183 100644 --- a/examples/transports/transports-livekit.py +++ b/examples/transports/transports-livekit.py @@ -22,7 +22,7 @@ from pipecat.frames.frames import ( ) from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -87,7 +87,7 @@ async def main(): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -100,7 +100,7 @@ async def main(): @transport.event_handler("on_first_participant_joined") async def on_first_participant_joined(transport, participant_id): await asyncio.sleep(1) - await task.queue_frame( + await worker.queue_frame( TTSSpeakFrame( "Hello there! How are you doing today? Would you like to talk about the weather?" ) @@ -116,7 +116,7 @@ async def main(): # convert data from bytes to string json_data = json.loads(data) - await task.queue_frames( + await worker.queue_frames( [ InterruptionFrame(), UserStartedSpeakingFrame(), @@ -131,7 +131,7 @@ async def main(): runner = PipelineRunner() - await runner.run(task) + await runner.run(worker) if __name__ == "__main__": diff --git a/examples/transports/transports-small-webrtc.py b/examples/transports/transports-small-webrtc.py index 2cb6d4bb0..8206c5442 100644 --- a/examples/transports/transports-small-webrtc.py +++ b/examples/transports/transports-small-webrtc.py @@ -20,7 +20,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -96,7 +96,7 @@ async def run_example(webrtc_connection: SmallWebRTCConnection): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -111,16 +111,16 @@ async def run_example(webrtc_connection: SmallWebRTCConnection): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=False) - await runner.run(task) + await runner.run(worker) @app.get("/", include_in_schema=False) @@ -150,7 +150,7 @@ async def offer(request: dict, background_tasks: BackgroundTasks): pcs_map.pop(webrtc_connection.pc_id, None) # Run example function with SmallWebRTC transport arguments. - background_tasks.add_task(run_example, pipecat_connection) + background_tasks.add_worker(run_example, pipecat_connection) answer = pipecat_connection.get_answer() # Updating the peer connection inside the map diff --git a/examples/transports/transports-vonage.py b/examples/transports/transports-vonage.py index cf85d4a9a..c98b8c015 100644 --- a/examples/transports/transports-vonage.py +++ b/examples/transports/transports-vonage.py @@ -20,7 +20,7 @@ from pipecat.frames.frames import LLMRunFrame from pipecat.observers.loggers.transcription_log_observer import TranscriptionLogObserver from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -109,7 +109,7 @@ Remember, your responses should be short. Just one or two sentences, usually. Re ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -123,11 +123,11 @@ Remember, your responses should be short. Just one or two sentences, usually. Re @event_handler("on_client_connected") async def on_client_connected(transport: VonageVideoConnectorTransport, client: object) -> None: logger.info("Client connected") - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) runner = PipelineRunner() - await runner.run(task) + await runner.run(worker) if __name__ == "__main__": diff --git a/examples/turn-management/turn-management-detect-user-idle.py b/examples/turn-management/turn-management-detect-user-idle.py index 8391e3908..f75d24d3d 100644 --- a/examples/turn-management/turn-management-detect-user-idle.py +++ b/examples/turn-management/turn-management-detect-user-idle.py @@ -24,7 +24,7 @@ from pipecat.frames.frames import ( ) from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -185,7 +185,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -213,22 +213,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(30) logger.info(f"Disabling idle detection") - await task.queue_frames([UserIdleTimeoutUpdateFrame(timeout=0)]) + await worker.queue_frames([UserIdleTimeoutUpdateFrame(timeout=0)]) await asyncio.sleep(30) logger.info(f"Enabling idle detection") - await task.queue_frames([UserIdleTimeoutUpdateFrame(timeout=5)]) + await worker.queue_frames([UserIdleTimeoutUpdateFrame(timeout=5)]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/turn-management/turn-management-filter-incomplete-turns-function-calling.py b/examples/turn-management/turn-management-filter-incomplete-turns-function-calling.py index 3cdd0110b..fb40fc256 100644 --- a/examples/turn-management/turn-management-filter-incomplete-turns-function-calling.py +++ b/examples/turn-management/turn-management-filter-incomplete-turns-function-calling.py @@ -26,7 +26,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( AssistantTurnStoppedMessage, @@ -149,7 +149,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -165,12 +165,12 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() @user_aggregator.event_handler("on_user_turn_stopped") async def on_user_turn_stopped(aggregator, strategy, message: UserTurnStoppedMessage): @@ -186,7 +186,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/turn-management/turn-management-filter-incomplete-turns.py b/examples/turn-management/turn-management-filter-incomplete-turns.py index 99c0394fb..a97bce8bd 100644 --- a/examples/turn-management/turn-management-filter-incomplete-turns.py +++ b/examples/turn-management/turn-management-filter-incomplete-turns.py @@ -25,7 +25,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( AssistantTurnStoppedMessage, @@ -121,7 +121,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -140,12 +140,12 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): "content": "Please introduce yourself to the user, asking them a question that will require a complete response. To start, say 'Let me start with a fun one. If you could travel anywhere in the world right now, where would you go and why?'", } ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() @user_aggregator.event_handler("on_user_turn_stopped") async def on_user_turn_stopped(aggregator, strategy, message: UserTurnStoppedMessage): @@ -161,7 +161,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/turn-management/turn-management-interruption-config.py b/examples/turn-management/turn-management-interruption-config.py index ee19075df..b680e5565 100644 --- a/examples/turn-management/turn-management-interruption-config.py +++ b/examples/turn-management/turn-management-interruption-config.py @@ -14,7 +14,7 @@ from pipecat.frames.frames import LLMRunFrame from pipecat.observers.loggers.transcription_log_observer import TranscriptionLogObserver from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -94,7 +94,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -111,16 +111,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/turn-management/turn-management-smart-turn-local-coreml.py b/examples/turn-management/turn-management-smart-turn-local-coreml.py index 68e831bba..e05f2d531 100644 --- a/examples/turn-management/turn-management-smart-turn-local-coreml.py +++ b/examples/turn-management/turn-management-smart-turn-local-coreml.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -117,7 +117,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -133,16 +133,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/turn-management/turn-management-smart-turn-local.py b/examples/turn-management/turn-management-smart-turn-local.py index 5509f0264..5ba66378f 100644 --- a/examples/turn-management/turn-management-smart-turn-local.py +++ b/examples/turn-management/turn-management-smart-turn-local.py @@ -16,7 +16,7 @@ from pipecat.metrics.metrics import TurnMetricsData from pipecat.observers.loggers.metrics_log_observer import MetricsLogObserver from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -88,7 +88,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -105,16 +105,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/turn-management/turn-management-turn-tracking-observer.py b/examples/turn-management/turn-management-turn-tracking-observer.py index 86f061906..d74ecb309 100644 --- a/examples/turn-management/turn-management-turn-tracking-observer.py +++ b/examples/turn-management/turn-management-turn-tracking-observer.py @@ -19,7 +19,7 @@ from pipecat.observers.startup_timing_observer import StartupTimingObserver from pipecat.observers.user_bot_latency_observer import UserBotLatencyObserver from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -138,7 +138,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): latency_observer = UserBotLatencyObserver() startup_observer = StartupTimingObserver() - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -168,7 +168,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): logger.info(f"Bot connected: {report.bot_connected_secs:.3f}s") logger.info(f"Client connected: {report.client_connected_secs:.3f}s") - turn_observer = task.turn_tracking_observer + turn_observer = worker.turn_tracking_observer if turn_observer: @turn_observer.event_handler("on_turn_started") @@ -194,16 +194,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/turn-management/turn-management-user-assistant-turns.py b/examples/turn-management/turn-management-user-assistant-turns.py index 879eb1cdc..a3d2256f6 100644 --- a/examples/turn-management/turn-management-user-assistant-turns.py +++ b/examples/turn-management/turn-management-user-assistant-turns.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( AssistantTurnStoppedMessage, @@ -156,7 +156,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -172,12 +172,12 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() @user_aggregator.event_handler("on_user_turn_stopped") async def on_user_turn_stopped(aggregator, strategy, message: UserTurnStoppedMessage): @@ -188,7 +188,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): await transcript_handler.on_assistant_transcript(message) runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/turn-management/turn-management-user-mute-strategy.py b/examples/turn-management/turn-management-user-mute-strategy.py index 0f9b24a8c..e7e36aafa 100644 --- a/examples/turn-management/turn-management-user-mute-strategy.py +++ b/examples/turn-management/turn-management-user-mute-strategy.py @@ -17,7 +17,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -128,7 +128,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -147,12 +147,12 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): "content": "Ask the user what city they'd like to know the weather for.", } ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() @user_aggregator.event_handler("on_user_mute_started") async def on_user_mute_started(aggregator): @@ -164,7 +164,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-anthropic.py b/examples/update-settings/llm/llm-anthropic.py index 885981ddd..3f3d86f21 100644 --- a/examples/update-settings/llm/llm-anthropic.py +++ b/examples/update-settings/llm/llm-anthropic.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -84,7 +84,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -99,22 +99,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Anthropic LLM settings: temperature=0.1") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame(delta=AnthropicLLMService.Settings(temperature=0.1)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-aws-bedrock.py b/examples/update-settings/llm/llm-aws-bedrock.py index 6facff628..2042b885e 100644 --- a/examples/update-settings/llm/llm-aws-bedrock.py +++ b/examples/update-settings/llm/llm-aws-bedrock.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -86,7 +86,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -101,22 +101,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating AWS Bedrock LLM settings: temperature=0.1") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame(delta=AWSBedrockLLMService.Settings(temperature=0.1)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-aws-nova-sonic.py b/examples/update-settings/llm/llm-aws-nova-sonic.py index 19ca3c805..8fb74ba6b 100644 --- a/examples/update-settings/llm/llm-aws-nova-sonic.py +++ b/examples/update-settings/llm/llm-aws-nova-sonic.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -73,7 +73,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -86,22 +86,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") context.add_message({"role": "developer", "content": "Tell me a fun fact."}) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating AWS Nova Sonic LLM settings: temperature=0.1") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame(delta=AWSNovaSonicLLMService.Settings(temperature=0.1)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-azure-realtime.py b/examples/update-settings/llm/llm-azure-realtime.py index 3d724bd53..dc2f22fce 100644 --- a/examples/update-settings/llm/llm-azure-realtime.py +++ b/examples/update-settings/llm/llm-azure-realtime.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( AssistantTurnStoppedMessage, @@ -79,7 +79,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -97,11 +97,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_connected") async def on_client_connected(transport, client): logger.info(f"Client connected") - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Azure Realtime LLM settings: output_modalities=['text']") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame( delta=AzureRealtimeLLMService.Settings( session_properties=events.SessionProperties(output_modalities=["text"]) @@ -111,7 +111,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): await asyncio.sleep(10) logger.info("Updating Azure Realtime LLM settings: output_modalities=['audio']") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame( delta=AzureRealtimeLLMService.Settings( session_properties=events.SessionProperties(output_modalities=["audio"]) @@ -122,11 +122,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-azure.py b/examples/update-settings/llm/llm-azure.py index 3f9f5da57..e7c0cc065 100644 --- a/examples/update-settings/llm/llm-azure.py +++ b/examples/update-settings/llm/llm-azure.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -86,7 +86,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -101,22 +101,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Azure LLM settings: temperature=0.1") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame(delta=AzureLLMService.Settings(temperature=0.1)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-cerebras.py b/examples/update-settings/llm/llm-cerebras.py index 232723a3e..30dee0c2e 100644 --- a/examples/update-settings/llm/llm-cerebras.py +++ b/examples/update-settings/llm/llm-cerebras.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -84,7 +84,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -99,22 +99,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Cerebras LLM settings: temperature=0.1") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame(delta=CerebrasLLMService.Settings(temperature=0.1)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-deepseek.py b/examples/update-settings/llm/llm-deepseek.py index a7df0469b..8cc45d763 100644 --- a/examples/update-settings/llm/llm-deepseek.py +++ b/examples/update-settings/llm/llm-deepseek.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -84,7 +84,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -99,22 +99,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating DeepSeek LLM settings: temperature=0.1") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame(delta=DeepSeekLLMService.Settings(temperature=0.1)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-fireworks.py b/examples/update-settings/llm/llm-fireworks.py index 154bb63ce..d69bbe5ff 100644 --- a/examples/update-settings/llm/llm-fireworks.py +++ b/examples/update-settings/llm/llm-fireworks.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -85,7 +85,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -100,22 +100,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Fireworks LLM settings: temperature=0.1") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame(delta=FireworksLLMService.Settings(temperature=0.1)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-gemini-live-vertex.py b/examples/update-settings/llm/llm-gemini-live-vertex.py index 3992be309..85ca682d0 100644 --- a/examples/update-settings/llm/llm-gemini-live-vertex.py +++ b/examples/update-settings/llm/llm-gemini-live-vertex.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -73,7 +73,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -88,22 +88,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Gemini Live Vertex LLM settings: temperature=0.1") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame(delta=GeminiLiveVertexLLMService.Settings(temperature=0.1)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-gemini-live.py b/examples/update-settings/llm/llm-gemini-live.py index 0c066648e..fd83c6662 100644 --- a/examples/update-settings/llm/llm-gemini-live.py +++ b/examples/update-settings/llm/llm-gemini-live.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -71,7 +71,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -86,22 +86,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Gemini Live LLM settings: temperature=0.1") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame(delta=GeminiLiveLLMService.Settings(temperature=0.1)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-google-vertex.py b/examples/update-settings/llm/llm-google-vertex.py index 7c4ca8446..5a69f4a50 100644 --- a/examples/update-settings/llm/llm-google-vertex.py +++ b/examples/update-settings/llm/llm-google-vertex.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -86,7 +86,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -101,22 +101,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Google Vertex LLM settings: temperature=0.1") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame(delta=GoogleVertexLLMService.Settings(temperature=0.1)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-google.py b/examples/update-settings/llm/llm-google.py index 69b474190..26f0f0d8c 100644 --- a/examples/update-settings/llm/llm-google.py +++ b/examples/update-settings/llm/llm-google.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -84,7 +84,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -99,22 +99,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Google LLM settings: temperature=0.1") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame(delta=GoogleLLMService.Settings(temperature=0.1)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-grok-realtime.py b/examples/update-settings/llm/llm-grok-realtime.py index 4ab28cdda..bcaf112c6 100644 --- a/examples/update-settings/llm/llm-grok-realtime.py +++ b/examples/update-settings/llm/llm-grok-realtime.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( AssistantTurnStoppedMessage, @@ -76,7 +76,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -94,11 +94,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_connected") async def on_client_connected(transport, client): logger.info(f"Client connected") - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Grok Realtime LLM settings: voice='Rex'") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame( delta=GrokRealtimeLLMService.Settings( session_properties=events.SessionProperties(voice="Rex") @@ -109,11 +109,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-grok.py b/examples/update-settings/llm/llm-grok.py index 463b27807..c1b7cd392 100644 --- a/examples/update-settings/llm/llm-grok.py +++ b/examples/update-settings/llm/llm-grok.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -84,7 +84,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -99,22 +99,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Grok LLM settings: temperature=0.1") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame(delta=GrokLLMService.Settings(temperature=0.1)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-groq.py b/examples/update-settings/llm/llm-groq.py index 365d8b4d4..8ddcd2e3d 100644 --- a/examples/update-settings/llm/llm-groq.py +++ b/examples/update-settings/llm/llm-groq.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -84,7 +84,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -99,22 +99,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Groq LLM settings: temperature=0.1") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame(delta=GroqLLMService.Settings(temperature=0.1)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-mistral.py b/examples/update-settings/llm/llm-mistral.py index 4aa66197e..9030815e7 100644 --- a/examples/update-settings/llm/llm-mistral.py +++ b/examples/update-settings/llm/llm-mistral.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -84,7 +84,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -99,22 +99,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Mistral LLM settings: temperature=0.1") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame(delta=MistralLLMService.Settings(temperature=0.1)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-nvidia.py b/examples/update-settings/llm/llm-nvidia.py index a44083821..2a5716edc 100644 --- a/examples/update-settings/llm/llm-nvidia.py +++ b/examples/update-settings/llm/llm-nvidia.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -85,7 +85,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -100,22 +100,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating NVIDIA LLM settings: temperature=0.1") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame(delta=NvidiaLLMService.Settings(temperature=0.1)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-ollama.py b/examples/update-settings/llm/llm-ollama.py index ac9892bee..638119434 100644 --- a/examples/update-settings/llm/llm-ollama.py +++ b/examples/update-settings/llm/llm-ollama.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -84,7 +84,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -99,22 +99,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating OLLama LLM settings: temperature=0.1") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame(delta=OLLamaLLMService.Settings(temperature=0.1)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-openai-realtime.py b/examples/update-settings/llm/llm-openai-realtime.py index 120d8a86e..51d32be30 100644 --- a/examples/update-settings/llm/llm-openai-realtime.py +++ b/examples/update-settings/llm/llm-openai-realtime.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( AssistantTurnStoppedMessage, @@ -76,7 +76,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -94,11 +94,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_connected") async def on_client_connected(transport, client): logger.info(f"Client connected") - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating OpenAI Realtime LLM settings: output_modalities=['text']") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame( delta=OpenAIRealtimeLLMService.Settings( session_properties=events.SessionProperties(output_modalities=["text"]) @@ -108,7 +108,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): await asyncio.sleep(10) logger.info("Updating OpenAI Realtime LLM settings: output_modalities=['audio']") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame( delta=OpenAIRealtimeLLMService.Settings( session_properties=events.SessionProperties(output_modalities=["audio"]) @@ -119,11 +119,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-openai-responses-http.py b/examples/update-settings/llm/llm-openai-responses-http.py index 0e7d6ec44..8cdb894eb 100644 --- a/examples/update-settings/llm/llm-openai-responses-http.py +++ b/examples/update-settings/llm/llm-openai-responses-http.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -84,7 +84,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -99,22 +99,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating OpenAI LLM settings: temperature=0.1") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame(delta=OpenAIResponsesHttpLLMService.Settings(temperature=0.1)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-openai-responses.py b/examples/update-settings/llm/llm-openai-responses.py index d4857bab1..b004377b4 100644 --- a/examples/update-settings/llm/llm-openai-responses.py +++ b/examples/update-settings/llm/llm-openai-responses.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -84,7 +84,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -99,11 +99,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating OpenAI LLM settings: temperature=1") - await task.queue_frame( + await worker.queue_frame( # Known OpenAI Python issue (as of 2026-03-31): setting temperature # to non-integer value results in failure. # https://github.com/openai/openai-python/issues/2919 @@ -113,11 +113,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-openai.py b/examples/update-settings/llm/llm-openai.py index dee6ba8cf..0c7bfc01a 100644 --- a/examples/update-settings/llm/llm-openai.py +++ b/examples/update-settings/llm/llm-openai.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -84,7 +84,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -99,22 +99,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating OpenAI LLM settings: temperature=0.1") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame(delta=OpenAILLMService.Settings(temperature=0.1)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-openrouter.py b/examples/update-settings/llm/llm-openrouter.py index 3c554b921..aeeaac716 100644 --- a/examples/update-settings/llm/llm-openrouter.py +++ b/examples/update-settings/llm/llm-openrouter.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -84,7 +84,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -99,22 +99,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating OpenRouter LLM settings: temperature=0.1") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame(delta=OpenRouterLLMService.Settings(temperature=0.1)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-perplexity.py b/examples/update-settings/llm/llm-perplexity.py index d1e2aae4a..1c334258f 100644 --- a/examples/update-settings/llm/llm-perplexity.py +++ b/examples/update-settings/llm/llm-perplexity.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -79,7 +79,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -94,22 +94,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Perplexity LLM settings: temperature=0.1") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame(delta=PerplexityLLMService.Settings(temperature=0.1)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-qwen.py b/examples/update-settings/llm/llm-qwen.py index 585a7c2da..c4827b42d 100644 --- a/examples/update-settings/llm/llm-qwen.py +++ b/examples/update-settings/llm/llm-qwen.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -85,7 +85,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -100,22 +100,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Qwen LLM settings: temperature=0.1") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame(delta=QwenLLMService.Settings(temperature=0.1)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-sambanova.py b/examples/update-settings/llm/llm-sambanova.py index c543fcee2..ab12e07f0 100644 --- a/examples/update-settings/llm/llm-sambanova.py +++ b/examples/update-settings/llm/llm-sambanova.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -84,7 +84,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -99,22 +99,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating SambaNova LLM settings: temperature=0.1") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame(delta=SambaNovaLLMService.Settings(temperature=0.1)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-sarvam.py b/examples/update-settings/llm/llm-sarvam.py index 2966f46b8..26d2eb47a 100644 --- a/examples/update-settings/llm/llm-sarvam.py +++ b/examples/update-settings/llm/llm-sarvam.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -88,7 +88,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -101,22 +101,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info("Client connected") context.add_message({"role": "user", "content": "Please introduce yourself to the user."}) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Sarvam LLM settings: temperature=0.1") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame(delta=SarvamLLMService.Settings(temperature=0.1)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info("Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-together.py b/examples/update-settings/llm/llm-together.py index 2e1a8cb7a..3d60b6b72 100644 --- a/examples/update-settings/llm/llm-together.py +++ b/examples/update-settings/llm/llm-together.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -84,7 +84,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -99,22 +99,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Together LLM settings: temperature=0.1") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame(delta=TogetherLLMService.Settings(temperature=0.1)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/llm/llm-ultravox-realtime.py b/examples/update-settings/llm/llm-ultravox-realtime.py index 4c530735e..f6ad54a27 100644 --- a/examples/update-settings/llm/llm-ultravox-realtime.py +++ b/examples/update-settings/llm/llm-ultravox-realtime.py @@ -17,7 +17,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, LLMUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( AssistantTurnStoppedMessage, @@ -87,7 +87,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -105,28 +105,28 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_connected") async def on_client_connected(transport, client): logger.info(f"Client connected") - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Ultravox Realtime LLM settings: output_medium=text") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame(delta=UltravoxRealtimeLLMService.Settings(output_medium="text")) ) await asyncio.sleep(10) logger.info("Updating Ultravox Realtime LLM settings: output_medium=voice") - await task.queue_frame( + await worker.queue_frame( LLMUpdateSettingsFrame(delta=UltravoxRealtimeLLMService.Settings(output_medium="voice")) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/stt/stt-assemblyai.py b/examples/update-settings/stt/stt-assemblyai.py index 276499bb1..530af6554 100644 --- a/examples/update-settings/stt/stt-assemblyai.py +++ b/examples/update-settings/stt/stt-assemblyai.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, STTUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -89,7 +89,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -107,11 +107,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(15) logger.info("🔄 Updating keyterms: Adding difficult names for boosting") - await task.queue_frame( + await worker.queue_frame( STTUpdateSettingsFrame( delta=AssemblyAISTTService.Settings( keyterms_prompt=["Xiomara", "Saoirse", "Krzystof", "Nguyen", "Pipecat"] @@ -123,11 +123,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/stt/stt-aws-transcribe.py b/examples/update-settings/stt/stt-aws-transcribe.py index 503ecae39..5f34df8e6 100644 --- a/examples/update-settings/stt/stt-aws-transcribe.py +++ b/examples/update-settings/stt/stt-aws-transcribe.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, STTUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -85,7 +85,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -100,22 +100,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating AWS Transcribe STT settings: language=es") - await task.queue_frame( + await worker.queue_frame( STTUpdateSettingsFrame(delta=AWSTranscribeSTTService.Settings(language=Language.ES)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/stt/stt-azure.py b/examples/update-settings/stt/stt-azure.py index e1f8b62ad..6e16d640e 100644 --- a/examples/update-settings/stt/stt-azure.py +++ b/examples/update-settings/stt/stt-azure.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, STTUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -88,7 +88,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -103,22 +103,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Azure STT settings: language=es") - await task.queue_frame( + await worker.queue_frame( STTUpdateSettingsFrame(delta=AzureSTTService.Settings(language=Language.ES)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/stt/stt-cartesia.py b/examples/update-settings/stt/stt-cartesia.py index 2f5602b8d..cd73471f5 100644 --- a/examples/update-settings/stt/stt-cartesia.py +++ b/examples/update-settings/stt/stt-cartesia.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, STTUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -85,7 +85,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -100,22 +100,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Cartesia STT settings: language=es") - await task.queue_frame( + await worker.queue_frame( STTUpdateSettingsFrame(delta=CartesiaSTTService.Settings(language=Language.ES)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/stt/stt-deepgram-flux.py b/examples/update-settings/stt/stt-deepgram-flux.py index f8810e2fd..3994b9ea3 100644 --- a/examples/update-settings/stt/stt-deepgram-flux.py +++ b/examples/update-settings/stt/stt-deepgram-flux.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, STTUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -98,7 +98,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -113,13 +113,13 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) # Update configure-able fields mid-stream (sent via Configure message, # no reconnect needed). await asyncio.sleep(10) logger.info("Updating Deepgram Flux STT settings: eot_threshold, keyterm") - await task.queue_frame( + await worker.queue_frame( STTUpdateSettingsFrame( delta=DeepgramFluxSTTService.Settings( eot_threshold=0.8, @@ -132,7 +132,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): # Sent as a Configure message — no reconnect needed. await asyncio.sleep(10) logger.info("Updating Deepgram Flux STT settings: language_hints=[es]") - await task.queue_frame( + await worker.queue_frame( STTUpdateSettingsFrame( delta=DeepgramFluxSTTService.Settings(language_hints=[Language.ES]) ) @@ -141,11 +141,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/stt/stt-deepgram-sagemaker.py b/examples/update-settings/stt/stt-deepgram-sagemaker.py index 05a655abc..e963c78ac 100644 --- a/examples/update-settings/stt/stt-deepgram-sagemaker.py +++ b/examples/update-settings/stt/stt-deepgram-sagemaker.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, STTUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -88,7 +88,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -103,12 +103,12 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) # NOTE: after this change, the bot will only respond if you speak Spanish await asyncio.sleep(10) logger.info("Updating Deepgram SageMaker STT settings: language=es, punctuate=False") - await task.queue_frame( + await worker.queue_frame( STTUpdateSettingsFrame( delta=DeepgramSageMakerSTTService.Settings( language=Language.ES, @@ -120,18 +120,18 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): # Old-style dict update (for backward-compat testing): # await asyncio.sleep(10) # logger.info("Updating Deepgram SageMaker STT settings via dict: punctuate=False, filler_words=True") - # await task.queue_frame( + # await worker.queue_frame( # STTUpdateSettingsFrame(settings={"punctuate": False, "filler_words": True}) # ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/stt/stt-deepgram.py b/examples/update-settings/stt/stt-deepgram.py index 9f345b1c3..082d4cde4 100644 --- a/examples/update-settings/stt/stt-deepgram.py +++ b/examples/update-settings/stt/stt-deepgram.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, STTUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -85,7 +85,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -100,12 +100,12 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) # NOTE: after this change, the bot will only respond if you speak Spanish await asyncio.sleep(10) logger.info("Updating Deepgram STT settings: language=es, punctuate=False") - await task.queue_frame( + await worker.queue_frame( STTUpdateSettingsFrame( delta=DeepgramSTTService.Settings( language=Language.ES, @@ -117,18 +117,18 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): # Old-style dict update (for backward-compat testing): # await asyncio.sleep(10) # logger.info("Updating Deepgram STT settings via dict: punctuate=False, filler_words=True") - # await task.queue_frame( + # await worker.queue_frame( # STTUpdateSettingsFrame(settings={"punctuate": False, "filler_words": True}) # ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/stt/stt-elevenlabs-realtime.py b/examples/update-settings/stt/stt-elevenlabs-realtime.py index 8a195ad48..ff0bf51b8 100644 --- a/examples/update-settings/stt/stt-elevenlabs-realtime.py +++ b/examples/update-settings/stt/stt-elevenlabs-realtime.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, STTUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -85,7 +85,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -100,11 +100,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating ElevenLabs Realtime STT settings: language=es") - await task.queue_frame( + await worker.queue_frame( STTUpdateSettingsFrame( delta=ElevenLabsRealtimeSTTService.Settings(language=Language.ES) ) @@ -113,11 +113,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/stt/stt-elevenlabs.py b/examples/update-settings/stt/stt-elevenlabs.py index 3b3623264..5f7ab8f9a 100644 --- a/examples/update-settings/stt/stt-elevenlabs.py +++ b/examples/update-settings/stt/stt-elevenlabs.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, STTUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -90,7 +90,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -105,22 +105,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating ElevenLabs STT settings: language=es") - await task.queue_frame( + await worker.queue_frame( STTUpdateSettingsFrame(delta=ElevenLabsSTTService.Settings(language=Language.ES)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/stt/stt-fal.py b/examples/update-settings/stt/stt-fal.py index 5dccd4d36..cb39f834f 100644 --- a/examples/update-settings/stt/stt-fal.py +++ b/examples/update-settings/stt/stt-fal.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, STTUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -84,7 +84,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -99,22 +99,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) - logger.info('Updating Fal STT settings: task="translate"') - await task.queue_frame( - STTUpdateSettingsFrame(delta=FalSTTService.Settings(task="translate")) + logger.info('Updating Fal STT settings: worker="translate"') + await worker.queue_frame( + STTUpdateSettingsFrame(delta=FalSTTService.Settings(worker="translate")) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/stt/stt-gladia.py b/examples/update-settings/stt/stt-gladia.py index 4449eff06..9f57d535f 100644 --- a/examples/update-settings/stt/stt-gladia.py +++ b/examples/update-settings/stt/stt-gladia.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, STTUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -85,7 +85,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -100,22 +100,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Gladia STT settings: language=es") - await task.queue_frame( + await worker.queue_frame( STTUpdateSettingsFrame(delta=GladiaSTTService.Settings(language=Language.ES)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/stt/stt-google.py b/examples/update-settings/stt/stt-google.py index 76ea1325d..ef01b13df 100644 --- a/examples/update-settings/stt/stt-google.py +++ b/examples/update-settings/stt/stt-google.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, STTUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -85,7 +85,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -100,22 +100,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Google STT settings: language=es") - await task.queue_frame( + await worker.queue_frame( STTUpdateSettingsFrame(delta=GoogleSTTService.Settings(language=Language.ES)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/stt/stt-gradium.py b/examples/update-settings/stt/stt-gradium.py index 1cab2b9e1..dbb8472bb 100644 --- a/examples/update-settings/stt/stt-gradium.py +++ b/examples/update-settings/stt/stt-gradium.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, STTUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -84,7 +84,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -99,22 +99,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Gradium STT settings: delay_in_frames=5") - await task.queue_frame( + await worker.queue_frame( STTUpdateSettingsFrame(delta=GradiumSTTService.Settings(delay_in_frames=16)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/stt/stt-groq.py b/examples/update-settings/stt/stt-groq.py index 033ed4c03..1cb98a4bc 100644 --- a/examples/update-settings/stt/stt-groq.py +++ b/examples/update-settings/stt/stt-groq.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, STTUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -86,7 +86,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -101,20 +101,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info('Updating Groq STT settings: language="es"') - await task.queue_frame(STTUpdateSettingsFrame(delta=GroqSTTService.Settings(language="es"))) + await worker.queue_frame( + STTUpdateSettingsFrame(delta=GroqSTTService.Settings(language="es")) + ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/stt/stt-nvidia-segmented.py b/examples/update-settings/stt/stt-nvidia-segmented.py index 1cce6fba2..9ca4f23e3 100644 --- a/examples/update-settings/stt/stt-nvidia-segmented.py +++ b/examples/update-settings/stt/stt-nvidia-segmented.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, STTUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -84,7 +84,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -99,22 +99,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating NVIDIA Segmented STT settings: profanity_filter=True") - await task.queue_frame( + await worker.queue_frame( STTUpdateSettingsFrame(delta=NvidiaSegmentedSTTService.Settings(profanity_filter=True)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/stt/stt-nvidia.py b/examples/update-settings/stt/stt-nvidia.py index 499269f86..1e77b94df 100644 --- a/examples/update-settings/stt/stt-nvidia.py +++ b/examples/update-settings/stt/stt-nvidia.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, STTUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -85,7 +85,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -100,22 +100,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating NVIDIA STT settings: language=es") - await task.queue_frame( + await worker.queue_frame( STTUpdateSettingsFrame(delta=NvidiaSTTService.Settings(language=Language.ES)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/stt/stt-openai-realtime.py b/examples/update-settings/stt/stt-openai-realtime.py index 33c4c4e7d..cc4f8e65c 100644 --- a/examples/update-settings/stt/stt-openai-realtime.py +++ b/examples/update-settings/stt/stt-openai-realtime.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, STTUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -85,7 +85,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -100,22 +100,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating OpenAI Realtime STT settings: language=es") - await task.queue_frame( + await worker.queue_frame( STTUpdateSettingsFrame(delta=OpenAIRealtimeSTTService.Settings(language=Language.ES)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/stt/stt-sarvam.py b/examples/update-settings/stt/stt-sarvam.py index 60da61359..535d5bfd2 100644 --- a/examples/update-settings/stt/stt-sarvam.py +++ b/examples/update-settings/stt/stt-sarvam.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, STTUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -85,7 +85,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -100,22 +100,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Sarvam STT settings: language=en-IN") - await task.queue_frame( + await worker.queue_frame( STTUpdateSettingsFrame(delta=SarvamSTTService.Settings(language=Language.EN_IN)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/stt/stt-soniox.py b/examples/update-settings/stt/stt-soniox.py index db30db29d..cc90798d4 100644 --- a/examples/update-settings/stt/stt-soniox.py +++ b/examples/update-settings/stt/stt-soniox.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, STTUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -80,7 +80,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -95,22 +95,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Soniox STT settings: language_hints=[es]") - await task.queue_frame( + await worker.queue_frame( STTUpdateSettingsFrame(delta=SonioxSTTService.Settings(language_hints=[Language.ES])) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/stt/stt-speechmatics.py b/examples/update-settings/stt/stt-speechmatics.py index f92d2ff7e..547fdfde3 100644 --- a/examples/update-settings/stt/stt-speechmatics.py +++ b/examples/update-settings/stt/stt-speechmatics.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, STTUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -92,7 +92,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -107,17 +107,17 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Speechmatics STT settings: language=es") - await task.queue_frame( + await worker.queue_frame( STTUpdateSettingsFrame(delta=SpeechmaticsSTTService.Settings(language=Language.ES)) ) await asyncio.sleep(10) logger.info("Updating Speechmatics STT settings: focus_speakers=['S1']") - await task.queue_frame( + await worker.queue_frame( STTUpdateSettingsFrame(delta=SpeechmaticsSTTService.Settings(focus_speakers=["S1"])) ) @@ -125,7 +125,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): logger.info( "Updating Speechmatics STT settings: speaker_active_format={text}" ) - await task.queue_frame( + await worker.queue_frame( STTUpdateSettingsFrame( delta=SpeechmaticsSTTService.Settings( speaker_active_format="{text}" @@ -136,11 +136,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/stt/stt-whisper-api.py b/examples/update-settings/stt/stt-whisper-api.py index 372e6a36e..95e40a6c5 100644 --- a/examples/update-settings/stt/stt-whisper-api.py +++ b/examples/update-settings/stt/stt-whisper-api.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, STTUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -91,7 +91,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -106,20 +106,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info('Updating OpenAI STT settings: language="es"') - await task.queue_frame(STTUpdateSettingsFrame(delta=BaseWhisperSTTSettings(language="es"))) + await worker.queue_frame( + STTUpdateSettingsFrame(delta=BaseWhisperSTTSettings(language="es")) + ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/stt/stt-whisper-mlx.py b/examples/update-settings/stt/stt-whisper-mlx.py index 7e9e5e4e1..3f7a06025 100644 --- a/examples/update-settings/stt/stt-whisper-mlx.py +++ b/examples/update-settings/stt/stt-whisper-mlx.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, STTUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -88,7 +88,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -103,12 +103,12 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) # NOTE: after this change, the bot will only respond if you speak Spanish await asyncio.sleep(10) logger.info("Updating Whisper MLX STT settings: model=TINY") - await task.queue_frame( + await worker.queue_frame( STTUpdateSettingsFrame( delta=WhisperSTTServiceMLX.Settings( model=MLXModel.TINY.value, @@ -119,11 +119,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/stt/stt-whisper.py b/examples/update-settings/stt/stt-whisper.py index e25f3915b..78d8fecd1 100644 --- a/examples/update-settings/stt/stt-whisper.py +++ b/examples/update-settings/stt/stt-whisper.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, STTUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -88,7 +88,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -103,11 +103,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Whisper STT settings: model=LARGE") - await task.queue_frame( + await worker.queue_frame( STTUpdateSettingsFrame( delta=WhisperSTTService.Settings( model=Model.LARGE.value, @@ -118,11 +118,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-asyncai-http.py b/examples/update-settings/tts/tts-asyncai-http.py index 5f6342114..a14efd0d2 100644 --- a/examples/update-settings/tts/tts-asyncai-http.py +++ b/examples/update-settings/tts/tts-asyncai-http.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -90,7 +90,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -105,22 +105,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating AsyncAI HTTP TTS settings: language=es") - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame(delta=AsyncAIHttpTTSService.Settings(language=Language.ES)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-asyncai.py b/examples/update-settings/tts/tts-asyncai.py index 3d7701288..e24636d82 100644 --- a/examples/update-settings/tts/tts-asyncai.py +++ b/examples/update-settings/tts/tts-asyncai.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -85,7 +85,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -100,22 +100,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating AsyncAI TTS settings: language=es") - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame(delta=AsyncAITTSService.Settings(language=Language.ES)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-aws-polly.py b/examples/update-settings/tts/tts-aws-polly.py index 6ddeaf04b..bb352a2ba 100644 --- a/examples/update-settings/tts/tts-aws-polly.py +++ b/examples/update-settings/tts/tts-aws-polly.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -79,7 +79,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -94,22 +94,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info('Updating AWS Polly TTS settings: rate="fast"') - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame(delta=AWSPollyTTSService.Settings(rate="fast")) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-azure-http.py b/examples/update-settings/tts/tts-azure-http.py index 5b3d6adb3..e75862ca1 100644 --- a/examples/update-settings/tts/tts-azure-http.py +++ b/examples/update-settings/tts/tts-azure-http.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -82,7 +82,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -97,22 +97,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info('Updating Azure TTS settings: rate="0.7", style="sad"') - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame(delta=AzureHttpTTSService.Settings(rate="0.7", style="sad")) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-azure.py b/examples/update-settings/tts/tts-azure.py index a3a1eb822..2896b3209 100644 --- a/examples/update-settings/tts/tts-azure.py +++ b/examples/update-settings/tts/tts-azure.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -82,7 +82,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -97,22 +97,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info('Updating Azure TTS settings: rate="0.7", style="sad"') - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame(delta=AzureTTSService.Settings(rate="0.7", style="sad")) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-camb.py b/examples/update-settings/tts/tts-camb.py index 874489d97..40831592f 100644 --- a/examples/update-settings/tts/tts-camb.py +++ b/examples/update-settings/tts/tts-camb.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -80,7 +80,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -95,11 +95,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Camb TTS settings: language -> Spanish, voice -> Pirate Captain") - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame( delta=CambTTSService.Settings(language=Language.ES, voice=147319) ) @@ -108,11 +108,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-cartesia-http.py b/examples/update-settings/tts/tts-cartesia-http.py index b126d1dee..85deb7458 100644 --- a/examples/update-settings/tts/tts-cartesia-http.py +++ b/examples/update-settings/tts/tts-cartesia-http.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -84,7 +84,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -99,11 +99,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Cartesia HTTP TTS settings: speed increased to 1.5") - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame( delta=CartesiaHttpTTSService.Settings(generation_config=GenerationConfig(speed=1.5)) ) @@ -112,11 +112,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-cartesia.py b/examples/update-settings/tts/tts-cartesia.py index 7f267a4d7..1d06d36a0 100644 --- a/examples/update-settings/tts/tts-cartesia.py +++ b/examples/update-settings/tts/tts-cartesia.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -86,7 +86,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -102,11 +102,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Cartesia TTS settings: speed increased to 1.5") - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame( delta=CartesiaTTSService.Settings(generation_config=GenerationConfig(speed=1.5)) ) @@ -115,11 +115,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-deepgram-http.py b/examples/update-settings/tts/tts-deepgram-http.py index 0aa24c4e5..0ac952d47 100644 --- a/examples/update-settings/tts/tts-deepgram-http.py +++ b/examples/update-settings/tts/tts-deepgram-http.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -86,7 +86,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -101,11 +101,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info('Updating Deepgram TTS settings: voice="aura-2-aries-en"') - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame( delta=DeepgramHttpTTSService.Settings(voice="aura-2-aries-en") ) @@ -113,7 +113,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): await asyncio.sleep(10) logger.info('Updating Deepgram TTS settings: voice="aura-2-luna-en"') - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame( delta=DeepgramHttpTTSService.Settings(voice="aura-2-luna-en") ) @@ -122,11 +122,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-deepgram-sagemaker.py b/examples/update-settings/tts/tts-deepgram-sagemaker.py index 47329b1f3..7b3ca1661 100644 --- a/examples/update-settings/tts/tts-deepgram-sagemaker.py +++ b/examples/update-settings/tts/tts-deepgram-sagemaker.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -83,7 +83,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -98,11 +98,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info('Updating Deepgram SageMaker TTS settings: voice="aura-2-aries-en"') - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame( delta=DeepgramSageMakerTTSService.Settings(voice="aura-2-aries-en") ) @@ -110,7 +110,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): await asyncio.sleep(10) logger.info('Updating Deepgram SageMaker TTS settings: voice="aura-2-luna-en"') - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame( delta=DeepgramSageMakerTTSService.Settings(voice="aura-2-luna-en") ) @@ -119,11 +119,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-deepgram.py b/examples/update-settings/tts/tts-deepgram.py index 8e532937a..d1410c9de 100644 --- a/examples/update-settings/tts/tts-deepgram.py +++ b/examples/update-settings/tts/tts-deepgram.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -79,7 +79,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -94,28 +94,28 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info('Updating Deepgram TTS settings: voice="aura-2-aries-en"') - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame(delta=DeepgramTTSService.Settings(voice="aura-2-aries-en")) ) await asyncio.sleep(10) logger.info('Updating Deepgram TTS settings: voice="aura-2-luna-en"') - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame(delta=DeepgramTTSService.Settings(voice="aura-2-luna-en")) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-elevenlabs-http.py b/examples/update-settings/tts/tts-elevenlabs-http.py index ac85a1452..9a9f97642 100644 --- a/examples/update-settings/tts/tts-elevenlabs-http.py +++ b/examples/update-settings/tts/tts-elevenlabs-http.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -92,7 +92,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -107,22 +107,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating ElevenLabs TTS settings: speed=0.7") - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame(delta=ElevenLabsHttpTTSService.Settings(speed=0.7)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-elevenlabs.py b/examples/update-settings/tts/tts-elevenlabs.py index 9aeadf993..740cc3779 100644 --- a/examples/update-settings/tts/tts-elevenlabs.py +++ b/examples/update-settings/tts/tts-elevenlabs.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -87,7 +87,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -102,17 +102,17 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating ElevenLabs TTS settings: speed=0.7") - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame(delta=ElevenLabsTTSService.Settings(speed=0.7)) ) await asyncio.sleep(10) logger.info("Updating ElevenLabs TTS settings: switching to a different voice") - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame( delta=ElevenLabsTTSService.Settings( voice=os.getenv( @@ -126,11 +126,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-fish.py b/examples/update-settings/tts/tts-fish.py index 44566d915..2e62e906d 100644 --- a/examples/update-settings/tts/tts-fish.py +++ b/examples/update-settings/tts/tts-fish.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -84,7 +84,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -99,22 +99,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Fish Audio TTS settings: prosody_speed=1.5") - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame(delta=FishAudioTTSService.Settings(prosody_speed=1.5)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-gemini.py b/examples/update-settings/tts/tts-gemini.py index a6b56ac54..94e3de01c 100644 --- a/examples/update-settings/tts/tts-gemini.py +++ b/examples/update-settings/tts/tts-gemini.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -88,7 +88,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -103,11 +103,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info('Updating Gemini TTS settings: prompt="Speak slowly and dramatically"') - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame( delta=GeminiTTSService.Settings(prompt="Speak slowly and dramatically") ) @@ -116,11 +116,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-google-http.py b/examples/update-settings/tts/tts-google-http.py index eef39d8f8..d007f691b 100644 --- a/examples/update-settings/tts/tts-google-http.py +++ b/examples/update-settings/tts/tts-google-http.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -79,7 +79,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -94,22 +94,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Google HTTP TTS settings: speaking_rate=1.4") - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame(delta=GoogleHttpTTSService.Settings(speaking_rate=1.4)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-google-stream.py b/examples/update-settings/tts/tts-google-stream.py index 2614022e7..3ddac5617 100644 --- a/examples/update-settings/tts/tts-google-stream.py +++ b/examples/update-settings/tts/tts-google-stream.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -79,7 +79,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -94,22 +94,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Google Stream TTS settings: speaking_rate=1.4") - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame(delta=GoogleTTSService.Settings(speaking_rate=1.4)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-gradium.py b/examples/update-settings/tts/tts-gradium.py index 73ed1f1d0..dbc18ccdd 100644 --- a/examples/update-settings/tts/tts-gradium.py +++ b/examples/update-settings/tts/tts-gradium.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -82,7 +82,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -97,22 +97,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info('Updating Gradium TTS settings: voice="LFZvm12tW_z0xfGo"') - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame(delta=GradiumTTSService.Settings(voice="LFZvm12tW_z0xfGo")) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-groq.py b/examples/update-settings/tts/tts-groq.py index 1926dfa96..ee492f69a 100644 --- a/examples/update-settings/tts/tts-groq.py +++ b/examples/update-settings/tts/tts-groq.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -79,7 +79,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -94,20 +94,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Groq TTS settings: voice=troy") - await task.queue_frame(TTSUpdateSettingsFrame(delta=GroqTTSService.Settings(voice="troy"))) + await worker.queue_frame( + TTSUpdateSettingsFrame(delta=GroqTTSService.Settings(voice="troy")) + ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-hume.py b/examples/update-settings/tts/tts-hume.py index 6399a908a..36a5bbc30 100644 --- a/examples/update-settings/tts/tts-hume.py +++ b/examples/update-settings/tts/tts-hume.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -82,7 +82,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -97,11 +97,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info('Updating Hume TTS settings: speed=2.0, description="Speak with excitement"') - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame( delta=HumeTTSService.Settings(speed=2.0, description="Speak with excitement") ) @@ -110,11 +110,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-inworld-http.py b/examples/update-settings/tts/tts-inworld-http.py index 28ea6c81d..081ad6ed2 100644 --- a/examples/update-settings/tts/tts-inworld-http.py +++ b/examples/update-settings/tts/tts-inworld-http.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -83,7 +83,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -98,11 +98,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Inworld TTS settings: speaking_rate=1.5, temperature=0.8") - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame( delta=InworldHttpTTSService.Settings(speaking_rate=1.5, temperature=0.8) ) @@ -111,11 +111,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-inworld.py b/examples/update-settings/tts/tts-inworld.py index 9bdd706e5..0808b148d 100644 --- a/examples/update-settings/tts/tts-inworld.py +++ b/examples/update-settings/tts/tts-inworld.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -79,7 +79,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -94,11 +94,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Inworld TTS settings: speaking_rate=1.5, temperature=0.8") - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame( delta=InworldTTSService.Settings(speaking_rate=1.5, temperature=0.8) ) @@ -107,11 +107,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-kokoro.py b/examples/update-settings/tts/tts-kokoro.py index 053dd630b..12573b6a7 100644 --- a/examples/update-settings/tts/tts-kokoro.py +++ b/examples/update-settings/tts/tts-kokoro.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -83,7 +83,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -98,22 +98,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info('Updating Kokoro TTS settings: voice="am_adam"') - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame(delta=KokoroTTSService.Settings(voice="am_adam")) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-lmnt.py b/examples/update-settings/tts/tts-lmnt.py index 68f5f6d12..edf8c0ab7 100644 --- a/examples/update-settings/tts/tts-lmnt.py +++ b/examples/update-settings/tts/tts-lmnt.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -82,7 +82,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -97,20 +97,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info('Updating LMNT TTS settings: voice="tyler"') - await task.queue_frame(TTSUpdateSettingsFrame(delta=LmntTTSService.Settings(voice="tyler"))) + await worker.queue_frame( + TTSUpdateSettingsFrame(delta=LmntTTSService.Settings(voice="tyler")) + ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-minimax.py b/examples/update-settings/tts/tts-minimax.py index 3a02adce0..6a7c105b7 100644 --- a/examples/update-settings/tts/tts-minimax.py +++ b/examples/update-settings/tts/tts-minimax.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -85,7 +85,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -100,11 +100,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info('Updating MiniMax TTS settings: speed=1.5, emotion="happy"') - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame( delta=MiniMaxHttpTTSService.Settings(speed=1.5, emotion="happy") ) @@ -113,11 +113,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-neuphonic-http.py b/examples/update-settings/tts/tts-neuphonic-http.py index a55d6fd6c..590f924af 100644 --- a/examples/update-settings/tts/tts-neuphonic-http.py +++ b/examples/update-settings/tts/tts-neuphonic-http.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -84,7 +84,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -99,22 +99,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Neuphonic HTTP TTS settings: speed=1.4") - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame(delta=NeuphonicHttpTTSService.Settings(speed=1.4)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-neuphonic.py b/examples/update-settings/tts/tts-neuphonic.py index fd37ec40e..4ab39ef2e 100644 --- a/examples/update-settings/tts/tts-neuphonic.py +++ b/examples/update-settings/tts/tts-neuphonic.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -79,7 +79,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -94,22 +94,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Neuphonic TTS settings: speed=1.4") - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame(delta=NeuphonicTTSService.Settings(speed=1.4)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-nvidia.py b/examples/update-settings/tts/tts-nvidia.py index e136db033..334ce3e59 100644 --- a/examples/update-settings/tts/tts-nvidia.py +++ b/examples/update-settings/tts/tts-nvidia.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -80,7 +80,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -95,22 +95,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info('Updating NVIDIA TTS settings: language="ES_US"') - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame(delta=NvidiaTTSService.Settings(language=Language.ES_US)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-openai.py b/examples/update-settings/tts/tts-openai.py index e23db32ac..82a5509ef 100644 --- a/examples/update-settings/tts/tts-openai.py +++ b/examples/update-settings/tts/tts-openai.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -79,7 +79,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( audio_out_sample_rate=24000, @@ -95,20 +95,20 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating OpenAI TTS settings: speed=2.0") - await task.queue_frame(TTSUpdateSettingsFrame(delta=OpenAITTSService.Settings(speed=2.0))) + await worker.queue_frame(TTSUpdateSettingsFrame(delta=OpenAITTSService.Settings(speed=2.0))) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-piper-http.py b/examples/update-settings/tts/tts-piper-http.py index ed943b5b0..bc6b94c24 100644 --- a/examples/update-settings/tts/tts-piper-http.py +++ b/examples/update-settings/tts/tts-piper-http.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -86,7 +86,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -101,11 +101,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info('Updating Piper HTTP TTS settings: voice="en_US-lessac-medium"') - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame( delta=PiperHttpTTSService.Settings(voice="en_US-lessac-medium") ) @@ -114,11 +114,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-piper.py b/examples/update-settings/tts/tts-piper.py index 710a9ad7f..dca4573da 100644 --- a/examples/update-settings/tts/tts-piper.py +++ b/examples/update-settings/tts/tts-piper.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -83,7 +83,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -98,25 +98,25 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) # NOTE: Local Piper loads the voice model once at init, so runtime voice # changes are not applied. This update will log an "unhandled settings" # warning. Use PiperHttpTTSService for dynamic voice switching. await asyncio.sleep(10) logger.info('Updating Piper TTS settings: voice="en_US-lessac-medium"') - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame(delta=PiperTTSService.Settings(voice="en_US-lessac-medium")) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-resembleai.py b/examples/update-settings/tts/tts-resembleai.py index 3f3a5e271..4642e25e3 100644 --- a/examples/update-settings/tts/tts-resembleai.py +++ b/examples/update-settings/tts/tts-resembleai.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -82,7 +82,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -97,11 +97,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating ResembleAI TTS settings: voice (changed)") - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame( delta=ResembleAITTSService.Settings(voice=os.environ["RESEMBLE_VOICE_UUID_ALT"]) ) @@ -110,11 +110,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-rime-http.py b/examples/update-settings/tts/tts-rime-http.py index 3e5b2d2e7..09188c3e5 100644 --- a/examples/update-settings/tts/tts-rime-http.py +++ b/examples/update-settings/tts/tts-rime-http.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -87,7 +87,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -102,22 +102,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Rime TTS settings: voice=rex") - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame(delta=RimeHttpTTSService.Settings(voice="rex")) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-rime.py b/examples/update-settings/tts/tts-rime.py index 314eeeb05..e81eb6804 100644 --- a/examples/update-settings/tts/tts-rime.py +++ b/examples/update-settings/tts/tts-rime.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -82,7 +82,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -97,20 +97,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Rime TTS settings: voice=bond") - await task.queue_frame(TTSUpdateSettingsFrame(delta=RimeTTSService.Settings(voice="bond"))) + await worker.queue_frame( + TTSUpdateSettingsFrame(delta=RimeTTSService.Settings(voice="bond")) + ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-sarvam-http.py b/examples/update-settings/tts/tts-sarvam-http.py index ec6911f5f..1dfcc041a 100644 --- a/examples/update-settings/tts/tts-sarvam-http.py +++ b/examples/update-settings/tts/tts-sarvam-http.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -83,7 +83,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -98,22 +98,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Sarvam TTS settings: pace=1.5") - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame(delta=SarvamHttpTTSService.Settings(pace=1.5)) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-sarvam.py b/examples/update-settings/tts/tts-sarvam.py index 9cb24ad93..1dfc882e0 100644 --- a/examples/update-settings/tts/tts-sarvam.py +++ b/examples/update-settings/tts/tts-sarvam.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -79,7 +79,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -94,20 +94,20 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info("Updating Sarvam TTS settings: pace=1.5") - await task.queue_frame(TTSUpdateSettingsFrame(delta=SarvamTTSService.Settings(pace=1.5))) + await worker.queue_frame(TTSUpdateSettingsFrame(delta=SarvamTTSService.Settings(pace=1.5))) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-speechmatics.py b/examples/update-settings/tts/tts-speechmatics.py index a4515739c..61212918b 100644 --- a/examples/update-settings/tts/tts-speechmatics.py +++ b/examples/update-settings/tts/tts-speechmatics.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -84,7 +84,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -99,22 +99,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info('Updating Speechmatics TTS settings: voice="theo"') - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame(delta=SpeechmaticsTTSService.Settings(voice="theo")) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/update-settings/tts/tts-xtts.py b/examples/update-settings/tts/tts-xtts.py index 0145e8c64..061b64723 100644 --- a/examples/update-settings/tts/tts-xtts.py +++ b/examples/update-settings/tts/tts-xtts.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame, TTSUpdateSettingsFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -88,7 +88,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -103,22 +103,22 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) await asyncio.sleep(10) logger.info('Updating XTTS TTS settings: voice="Ana Florence"') - await task.queue_frame( + await worker.queue_frame( TTSUpdateSettingsFrame(delta=XTTSService.Settings(voice="Ana Florence")) ) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/video-avatar/video-avatar-heygen-transport.py b/examples/video-avatar/video-avatar-heygen-transport.py index 0ea504520..5cc1a390b 100644 --- a/examples/video-avatar/video-avatar-heygen-transport.py +++ b/examples/video-avatar/video-avatar-heygen-transport.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_response_universal import ( LLMContext, LLMContextAggregatorPair, @@ -86,7 +86,7 @@ async def main(): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -104,16 +104,16 @@ async def main(): "content": "Start by saying 'Hello' and then a short greeting.", } ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner() - await runner.run(task) + await runner.run(worker) if __name__ == "__main__": diff --git a/examples/video-avatar/video-avatar-heygen-video-service.py b/examples/video-avatar/video-avatar-heygen-video-service.py index a48c42758..b7ffb4b94 100644 --- a/examples/video-avatar/video-avatar-heygen-video-service.py +++ b/examples/video-avatar/video-avatar-heygen-video-service.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -106,7 +106,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -137,16 +137,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): "content": "Start by saying 'Hello' and then a short greeting.", } ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/video-avatar/video-avatar-lemonslice-transport.py b/examples/video-avatar/video-avatar-lemonslice-transport.py index 08dd48aa3..3899c0393 100644 --- a/examples/video-avatar/video-avatar-lemonslice-transport.py +++ b/examples/video-avatar/video-avatar-lemonslice-transport.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -87,7 +87,7 @@ async def main(): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( audio_in_sample_rate=16000, @@ -107,12 +107,12 @@ async def main(): "content": "Start by greeting the user and ask how you can help.", } ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, participant): logger.info("Client disconnected") - await task.cancel() + await worker.cancel() @transport.event_handler("on_avatar_connected") async def on_avatar_connected(transport, participant): @@ -124,7 +124,7 @@ async def main(): runner = PipelineRunner() - await runner.run(task) + await runner.run(worker) if __name__ == "__main__": diff --git a/examples/video-avatar/video-avatar-simli-video-service.py b/examples/video-avatar/video-avatar-simli-video-service.py index c91623253..7350a47dc 100644 --- a/examples/video-avatar/video-avatar-simli-video-service.py +++ b/examples/video-avatar/video-avatar-simli-video-service.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -96,7 +96,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -109,15 +109,15 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Start conversation - empty prompt to let LLM follow system instructions - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/video-avatar/video-avatar-tavus-transport.py b/examples/video-avatar/video-avatar-tavus-transport.py index 566538dbb..ed336d648 100644 --- a/examples/video-avatar/video-avatar-tavus-transport.py +++ b/examples/video-avatar/video-avatar-tavus-transport.py @@ -16,7 +16,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -81,7 +81,7 @@ async def main(): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( audio_in_sample_rate=16000, @@ -109,16 +109,16 @@ async def main(): "content": "Start by greeting the user and ask how you can help.", } ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, participant): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner() - await runner.run(task) + await runner.run(worker) if __name__ == "__main__": diff --git a/examples/video-avatar/video-avatar-tavus-video-service.py b/examples/video-avatar/video-avatar-tavus-video-service.py index ce3075074..194622dd6 100644 --- a/examples/video-avatar/video-avatar-tavus-video-service.py +++ b/examples/video-avatar/video-avatar-tavus-video-service.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -100,7 +100,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( audio_in_sample_rate=16000, @@ -121,16 +121,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): "content": "Start by greeting the user and ask how you can help.", } ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/video-processing/video-processing-custom-video-track.py b/examples/video-processing/video-processing-custom-video-track.py index 03b74b04f..797f98875 100644 --- a/examples/video-processing/video-processing-custom-video-track.py +++ b/examples/video-processing/video-processing-custom-video-track.py @@ -31,7 +31,7 @@ from pipecat.frames.frames import ( ) from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineTask +from pipecat.pipeline.worker import PipelineWorker from pipecat.processors.frame_processor import FrameDirection, FrameProcessor from pipecat.runner.types import RunnerArguments from pipecat.runner.utils import create_transport @@ -177,7 +177,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): generator = VideoPatternGenerator(WIDTH, HEIGHT, FPS) blue_tint = BlueTintProcessor(destination="blue") - task = PipelineTask( + worker = PipelineWorker( Pipeline([generator, blue_tint, transport.output()]), idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, ) @@ -189,10 +189,10 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info("Client disconnected") - await task.queue_frame(EndFrame()) + await worker.queue_frame(EndFrame()) runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/video-processing/video-processing-gstreamer-filesrc.py b/examples/video-processing/video-processing-gstreamer-filesrc.py index f1c3062b4..ca4ff4545 100644 --- a/examples/video-processing/video-processing-gstreamer-filesrc.py +++ b/examples/video-processing/video-processing-gstreamer-filesrc.py @@ -11,7 +11,7 @@ from loguru import logger from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineTask +from pipecat.pipeline.worker import PipelineWorker from pipecat.processors.gstreamer.pipeline_source import GStreamerPipelineSource from pipecat.runner.types import RunnerArguments from pipecat.runner.utils import create_transport @@ -58,7 +58,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, ) @@ -70,11 +70,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/video-processing/video-processing-gstreamer-videotestsrc.py b/examples/video-processing/video-processing-gstreamer-videotestsrc.py index 8398f1f7f..e9d0855f9 100644 --- a/examples/video-processing/video-processing-gstreamer-videotestsrc.py +++ b/examples/video-processing/video-processing-gstreamer-videotestsrc.py @@ -10,7 +10,7 @@ from loguru import logger from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineTask +from pipecat.pipeline.worker import PipelineWorker from pipecat.processors.gstreamer.pipeline_source import GStreamerPipelineSource from pipecat.runner.types import RunnerArguments from pipecat.runner.utils import create_transport @@ -54,14 +54,14 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, ) runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/video-processing/video-processing-local-mirror.py b/examples/video-processing/video-processing-local-mirror.py index 217136e58..31756c9a2 100644 --- a/examples/video-processing/video-processing-local-mirror.py +++ b/examples/video-processing/video-processing-local-mirror.py @@ -19,7 +19,7 @@ from pipecat.frames.frames import ( ) from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.frame_processor import FrameDirection, FrameProcessor from pipecat.runner.types import RunnerArguments from pipecat.runner.utils import create_transport, maybe_capture_participant_camera @@ -93,14 +93,14 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): pipeline = Pipeline([transport.input(), MirrorProcessor(), tk_transport.output()]) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams(), idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, ) async def run_tk(): - while not task.has_finished(): + while not worker.has_finished(): tk_root.update() tk_root.update_idletasks() await asyncio.sleep(0.1) @@ -113,11 +113,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await asyncio.gather(runner.run(task), run_tk()) + await asyncio.gather(runner.run(worker), run_tk()) async def bot(runner_args: RunnerArguments): diff --git a/examples/video-processing/video-processing-mirror.py b/examples/video-processing/video-processing-mirror.py index 478fe9daf..fc14325fc 100644 --- a/examples/video-processing/video-processing-mirror.py +++ b/examples/video-processing/video-processing-mirror.py @@ -17,7 +17,7 @@ from pipecat.frames.frames import ( ) from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.frame_processor import FrameDirection, FrameProcessor from pipecat.runner.types import RunnerArguments from pipecat.runner.utils import create_transport @@ -76,7 +76,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): pipeline = Pipeline([transport.input(), MirrorProcessor(), transport.output()]) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams(), idle_timeout_secs=runner_args.pipeline_idle_timeout_secs, @@ -89,11 +89,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/video-processing/video-processing.py b/examples/video-processing/video-processing.py index 812de5b03..390e6eeff 100644 --- a/examples/video-processing/video-processing.py +++ b/examples/video-processing/video-processing.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import Frame, InputImageRawFrame, LLMRunFrame, OutputImageRawFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -122,7 +122,7 @@ async def run_bot(pipecat_transport): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -130,7 +130,7 @@ async def run_bot(pipecat_transport): ), ) - @task.rtvi.event_handler("on_client_ready") + @worker.rtvi.event_handler("on_client_ready") async def on_client_ready(rtvi): logger.info("Pipecat client ready.") # Kick off the conversation. @@ -140,7 +140,7 @@ async def run_bot(pipecat_transport): "content": "Start by greeting the user warmly and introducing yourself.", } ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @pipecat_transport.event_handler("on_client_connected") async def on_client_connected(transport, participant): @@ -153,11 +153,11 @@ async def run_bot(pipecat_transport): @pipecat_transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info("Pipecat Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=False, force_gc=True) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/vision/vision-anthropic.py b/examples/vision/vision-anthropic.py index d02cf8b95..19078e8e8 100644 --- a/examples/vision/vision-anthropic.py +++ b/examples/vision/vision-anthropic.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -83,7 +83,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -115,16 +115,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): text=question, ) context.add_message(message) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/vision/vision-aws.py b/examples/vision/vision-aws.py index 8905f1e9f..ed181f585 100644 --- a/examples/vision/vision-aws.py +++ b/examples/vision/vision-aws.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -85,7 +85,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -117,16 +117,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): text=question, ) context.add_message(message) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/vision/vision-gemini-flash.py b/examples/vision/vision-gemini-flash.py index b94942766..6870e80e1 100644 --- a/examples/vision/vision-gemini-flash.py +++ b/examples/vision/vision-gemini-flash.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -83,7 +83,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -115,16 +115,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): text=question, ) context.add_message(message) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/vision/vision-moondream.py b/examples/vision/vision-moondream.py index 5b2a3f2e7..aa6b942f9 100644 --- a/examples/vision/vision-moondream.py +++ b/examples/vision/vision-moondream.py @@ -14,7 +14,7 @@ from PIL import Image from pipecat.frames.frames import UserImageRawFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.runner.types import RunnerArguments from pipecat.runner.utils import create_transport from pipecat.services.cartesia.tts import CartesiaTTSService @@ -57,7 +57,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -82,7 +82,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): # Describe the image. image = Image.open(image_path) - await task.queue_frames( + await worker.queue_frames( [ UserImageRawFrame( image=image.tobytes(), @@ -96,11 +96,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/vision/vision-openai-responses-http.py b/examples/vision/vision-openai-responses-http.py index 86c63a266..802eba940 100644 --- a/examples/vision/vision-openai-responses-http.py +++ b/examples/vision/vision-openai-responses-http.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -83,7 +83,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -115,16 +115,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): text=question, ) context.add_message(message) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/vision/vision-openai-responses.py b/examples/vision/vision-openai-responses.py index d66c2b2ba..21f3fb64b 100644 --- a/examples/vision/vision-openai-responses.py +++ b/examples/vision/vision-openai-responses.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -83,7 +83,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -115,16 +115,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): text=question, ) context.add_message(message) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/vision/vision-openai.py b/examples/vision/vision-openai.py index 2dfede380..2bf098e56 100644 --- a/examples/vision/vision-openai.py +++ b/examples/vision/vision-openai.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -83,7 +83,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -115,16 +115,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): text=question, ) context.add_message(message) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-aicoustics.py b/examples/voice/voice-aicoustics.py index 386f80cbd..46f10bbee 100644 --- a/examples/voice/voice-aicoustics.py +++ b/examples/voice/voice-aicoustics.py @@ -16,7 +16,7 @@ from pipecat.audio.filters.aic_filter import AICFilter from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -115,7 +115,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -132,7 +132,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @audiobuffer.event_handler("on_audio_data") async def on_audio_data(buffer, audio, sample_rate, num_channels): @@ -152,11 +152,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-assemblyai-turn-detection.py b/examples/voice/voice-assemblyai-turn-detection.py index 26662872e..bdaa56ddc 100644 --- a/examples/voice/voice-assemblyai-turn-detection.py +++ b/examples/voice/voice-assemblyai-turn-detection.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -140,7 +140,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -156,16 +156,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-assemblyai.py b/examples/voice/voice-assemblyai.py index 826b4b020..7e6bc14f9 100644 --- a/examples/voice/voice-assemblyai.py +++ b/examples/voice/voice-assemblyai.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -89,7 +89,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -105,16 +105,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-asyncai-http.py b/examples/voice/voice-asyncai-http.py index 480ff9bfd..812c2054a 100644 --- a/examples/voice/voice-asyncai-http.py +++ b/examples/voice/voice-asyncai-http.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -91,7 +91,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -107,16 +107,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-asyncai.py b/examples/voice/voice-asyncai.py index 46240542c..42deabdfd 100644 --- a/examples/voice/voice-asyncai.py +++ b/examples/voice/voice-asyncai.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -87,7 +87,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -103,16 +103,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-aws-strands.py b/examples/voice/voice-aws-strands.py index ee5d77aad..6c9f1a895 100644 --- a/examples/voice/voice-aws-strands.py +++ b/examples/voice/voice-aws-strands.py @@ -12,7 +12,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMMessagesAppendFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -133,7 +133,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -146,7 +146,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") # Kick off the conversation. - await task.queue_frames( + await worker.queue_frames( [ LLMMessagesAppendFrame( messages=[ @@ -163,11 +163,11 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-aws.py b/examples/voice/voice-aws.py index ae9f59943..7e82c6c44 100644 --- a/examples/voice/voice-aws.py +++ b/examples/voice/voice-aws.py @@ -12,7 +12,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -88,7 +88,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -104,16 +104,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-azure-http.py b/examples/voice/voice-azure-http.py index c3872cbfb..bdeb6481a 100644 --- a/examples/voice/voice-azure-http.py +++ b/examples/voice/voice-azure-http.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -89,7 +89,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -105,16 +105,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-azure.py b/examples/voice/voice-azure.py index 708c96e18..3465461e4 100644 --- a/examples/voice/voice-azure.py +++ b/examples/voice/voice-azure.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -89,7 +89,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -105,16 +105,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-camb.py b/examples/voice/voice-camb.py index a84b3c3ec..e351267b1 100644 --- a/examples/voice/voice-camb.py +++ b/examples/voice/voice-camb.py @@ -13,7 +13,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -86,7 +86,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -102,16 +102,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info("Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-cartesia-http.py b/examples/voice/voice-cartesia-http.py index f2f02ec7d..9944c5073 100644 --- a/examples/voice/voice-cartesia-http.py +++ b/examples/voice/voice-cartesia-http.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -89,7 +89,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -105,16 +105,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-cartesia.py b/examples/voice/voice-cartesia.py index 2a399b954..fc01c9e0e 100644 --- a/examples/voice/voice-cartesia.py +++ b/examples/voice/voice-cartesia.py @@ -13,7 +13,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -85,7 +85,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -101,16 +101,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-deepgram-flux-sagemaker.py b/examples/voice/voice-deepgram-flux-sagemaker.py index c0426ab15..6e4536c24 100644 --- a/examples/voice/voice-deepgram-flux-sagemaker.py +++ b/examples/voice/voice-deepgram-flux-sagemaker.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -109,7 +109,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -123,12 +123,12 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): logger.info(f"Client connected") # Kick off the conversation. context.add_message({"role": "user", "content": "Please introduce yourself to the user."}) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() @stt.event_handler("on_update") async def on_deepgram_flux_update(stt, transcript): @@ -136,7 +136,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-deepgram-flux.py b/examples/voice/voice-deepgram-flux.py index 7e9ec3938..a89ed68d8 100644 --- a/examples/voice/voice-deepgram-flux.py +++ b/examples/voice/voice-deepgram-flux.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_response_universal import ( LLMContext, LLMContextAggregatorPair, @@ -96,7 +96,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -112,12 +112,12 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() @stt.event_handler("on_update") async def on_deepgram_flux_update(stt, transcript): @@ -125,7 +125,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-deepgram-http.py b/examples/voice/voice-deepgram-http.py index d53255ca0..571bf3233 100644 --- a/examples/voice/voice-deepgram-http.py +++ b/examples/voice/voice-deepgram-http.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -90,7 +90,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -106,16 +106,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-deepgram-sagemaker.py b/examples/voice/voice-deepgram-sagemaker.py index 30e861518..50a23beee 100644 --- a/examples/voice/voice-deepgram-sagemaker.py +++ b/examples/voice/voice-deepgram-sagemaker.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -101,7 +101,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -117,16 +117,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-deepgram.py b/examples/voice/voice-deepgram.py index 323fd34a3..6f5ef6b0c 100644 --- a/examples/voice/voice-deepgram.py +++ b/examples/voice/voice-deepgram.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -87,7 +87,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -103,16 +103,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-elevenlabs-http.py b/examples/voice/voice-elevenlabs-http.py index 87e8dc2ca..69b42dbe6 100644 --- a/examples/voice/voice-elevenlabs-http.py +++ b/examples/voice/voice-elevenlabs-http.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -94,7 +94,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -110,16 +110,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-elevenlabs.py b/examples/voice/voice-elevenlabs.py index 8f61bb665..fc0333492 100644 --- a/examples/voice/voice-elevenlabs.py +++ b/examples/voice/voice-elevenlabs.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -87,7 +87,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -103,16 +103,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-fal.py b/examples/voice/voice-fal.py index d4b1e4a52..b2bf0568d 100644 --- a/examples/voice/voice-fal.py +++ b/examples/voice/voice-fal.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -92,7 +92,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -108,16 +108,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-fish.py b/examples/voice/voice-fish.py index 0ff8503c8..b995eb019 100644 --- a/examples/voice/voice-fish.py +++ b/examples/voice/voice-fish.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -87,7 +87,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -103,16 +103,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-gladia-vad.py b/examples/voice/voice-gladia-vad.py index c0eea8841..de884bea3 100644 --- a/examples/voice/voice-gladia-vad.py +++ b/examples/voice/voice-gladia-vad.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -104,7 +104,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -120,15 +120,15 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-gladia.py b/examples/voice/voice-gladia.py index a6a909a9a..cc17786b1 100644 --- a/examples/voice/voice-gladia.py +++ b/examples/voice/voice-gladia.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -99,7 +99,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -115,15 +115,15 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-google-audio-in.py b/examples/voice/voice-google-audio-in.py index f6a350411..63daac37a 100644 --- a/examples/voice/voice-google-audio-in.py +++ b/examples/voice/voice-google-audio-in.py @@ -27,7 +27,7 @@ from pipecat.frames.frames import ( ) from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -256,7 +256,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -272,16 +272,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-google-gemini-tts.py b/examples/voice/voice-google-gemini-tts.py index 8aa7e3c39..fb58e5216 100644 --- a/examples/voice/voice-google-gemini-tts.py +++ b/examples/voice/voice-google-gemini-tts.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -113,7 +113,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -132,16 +132,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): "content": "You are an AI assistant. You can help with a variety of tasks. Introduce yourself and ask the user what they would like to know.", } ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-google-http.py b/examples/voice/voice-google-http.py index 0e642b8ca..3bf8e7a65 100644 --- a/examples/voice/voice-google-http.py +++ b/examples/voice/voice-google-http.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -99,7 +99,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -115,16 +115,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-google-image.py b/examples/voice/voice-google-image.py index 52949b357..34cc83fc4 100644 --- a/examples/voice/voice-google-image.py +++ b/examples/voice/voice-google-image.py @@ -26,7 +26,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -108,7 +108,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -124,16 +124,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-google.py b/examples/voice/voice-google.py index 9f6a43874..8b3695628 100644 --- a/examples/voice/voice-google.py +++ b/examples/voice/voice-google.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -99,7 +99,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -115,16 +115,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-gradium.py b/examples/voice/voice-gradium.py index e147d03e1..421b3fd8d 100644 --- a/examples/voice/voice-gradium.py +++ b/examples/voice/voice-gradium.py @@ -13,7 +13,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -91,7 +91,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -107,16 +107,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-groq.py b/examples/voice/voice-groq.py index 9b1b34da4..8bec6eedf 100644 --- a/examples/voice/voice-groq.py +++ b/examples/voice/voice-groq.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -82,7 +82,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -98,16 +98,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-hume.py b/examples/voice/voice-hume.py index bda68d6f9..00b107650 100644 --- a/examples/voice/voice-hume.py +++ b/examples/voice/voice-hume.py @@ -14,7 +14,7 @@ from pipecat.frames.frames import LLMRunFrame, TTSTextFrame from pipecat.observers.loggers.debug_log_observer import DebugLogObserver, FrameEndpoint from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -89,7 +89,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -116,16 +116,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-inworld-http.py b/examples/voice/voice-inworld-http.py index 2a388f62b..9efaeed9a 100644 --- a/examples/voice/voice-inworld-http.py +++ b/examples/voice/voice-inworld-http.py @@ -15,7 +15,7 @@ from pipecat.frames.frames import LLMRunFrame, TTSTextFrame from pipecat.observers.loggers.debug_log_observer import DebugLogObserver, FrameEndpoint from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -90,7 +90,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -113,16 +113,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info("Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-inworld.py b/examples/voice/voice-inworld.py index b8603efc9..94ab4ad04 100644 --- a/examples/voice/voice-inworld.py +++ b/examples/voice/voice-inworld.py @@ -13,7 +13,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -85,7 +85,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -101,16 +101,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info("Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-kokoro.py b/examples/voice/voice-kokoro.py index fe74589dc..f1655cba8 100644 --- a/examples/voice/voice-kokoro.py +++ b/examples/voice/voice-kokoro.py @@ -13,7 +13,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -85,7 +85,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -101,16 +101,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-krisp-viva.py b/examples/voice/voice-krisp-viva.py index fa6498616..fd33c33ed 100644 --- a/examples/voice/voice-krisp-viva.py +++ b/examples/voice/voice-krisp-viva.py @@ -39,7 +39,7 @@ from pipecat.metrics.metrics import TurnMetricsData from pipecat.observers.loggers.metrics_log_observer import MetricsLogObserver from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -127,7 +127,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -144,16 +144,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-langchain.py b/examples/voice/voice-langchain.py index 19fda0c91..4371e11b0 100644 --- a/examples/voice/voice-langchain.py +++ b/examples/voice/voice-langchain.py @@ -19,7 +19,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -113,7 +113,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -132,16 +132,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please briefly introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-lmnt.py b/examples/voice/voice-lmnt.py index 6faa4c31c..814912867 100644 --- a/examples/voice/voice-lmnt.py +++ b/examples/voice/voice-lmnt.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -86,7 +86,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -102,16 +102,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-minimax.py b/examples/voice/voice-minimax.py index 9e4291af7..0f67a43d2 100644 --- a/examples/voice/voice-minimax.py +++ b/examples/voice/voice-minimax.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -93,7 +93,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -109,16 +109,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-mistral.py b/examples/voice/voice-mistral.py index 4664caf22..5b62bfab0 100644 --- a/examples/voice/voice-mistral.py +++ b/examples/voice/voice-mistral.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -87,7 +87,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -103,16 +103,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-neuphonic-http.py b/examples/voice/voice-neuphonic-http.py index 9cbcc8ede..4e9d193f4 100644 --- a/examples/voice/voice-neuphonic-http.py +++ b/examples/voice/voice-neuphonic-http.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -91,7 +91,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -107,16 +107,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-neuphonic.py b/examples/voice/voice-neuphonic.py index 1ea90fd51..2786589ef 100644 --- a/examples/voice/voice-neuphonic.py +++ b/examples/voice/voice-neuphonic.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -86,7 +86,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -102,16 +102,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-nvidia-sagemaker.py b/examples/voice/voice-nvidia-sagemaker.py index ac0c6a365..bffd864f3 100644 --- a/examples/voice/voice-nvidia-sagemaker.py +++ b/examples/voice/voice-nvidia-sagemaker.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -89,7 +89,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -105,16 +105,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-nvidia.py b/examples/voice/voice-nvidia.py index 7f84134d3..bc4033380 100644 --- a/examples/voice/voice-nvidia.py +++ b/examples/voice/voice-nvidia.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -82,7 +82,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -98,16 +98,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-openai-http.py b/examples/voice/voice-openai-http.py index 1483acb69..2750e96b7 100644 --- a/examples/voice/voice-openai-http.py +++ b/examples/voice/voice-openai-http.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -92,7 +92,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( audio_out_sample_rate=24000, @@ -109,16 +109,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-openai-responses-http.py b/examples/voice/voice-openai-responses-http.py index b3f49cbe1..ec8782cdb 100644 --- a/examples/voice/voice-openai-responses-http.py +++ b/examples/voice/voice-openai-responses-http.py @@ -13,7 +13,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -85,7 +85,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -101,16 +101,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-openai-responses.py b/examples/voice/voice-openai-responses.py index d1ecc0946..c928382d3 100644 --- a/examples/voice/voice-openai-responses.py +++ b/examples/voice/voice-openai-responses.py @@ -13,7 +13,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -85,7 +85,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -101,16 +101,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-openai.py b/examples/voice/voice-openai.py index f5c30d681..9587ccc73 100644 --- a/examples/voice/voice-openai.py +++ b/examples/voice/voice-openai.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -86,7 +86,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( audio_out_sample_rate=24000, @@ -103,16 +103,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-piper.py b/examples/voice/voice-piper.py index dffdd4d34..d58bf591b 100644 --- a/examples/voice/voice-piper.py +++ b/examples/voice/voice-piper.py @@ -13,7 +13,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -85,7 +85,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -101,16 +101,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-resemble.py b/examples/voice/voice-resemble.py index f3c2a1336..4f2f02c74 100644 --- a/examples/voice/voice-resemble.py +++ b/examples/voice/voice-resemble.py @@ -13,7 +13,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -85,7 +85,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -101,16 +101,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-rime-http.py b/examples/voice/voice-rime-http.py index 72bc63ca7..6e9d6ef60 100644 --- a/examples/voice/voice-rime-http.py +++ b/examples/voice/voice-rime-http.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -93,7 +93,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -109,16 +109,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-rime.py b/examples/voice/voice-rime.py index bd1f50dbc..e97737d71 100644 --- a/examples/voice/voice-rime.py +++ b/examples/voice/voice-rime.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -86,7 +86,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -102,16 +102,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-sarvam-http.py b/examples/voice/voice-sarvam-http.py index b70f44e2a..b7dc3d578 100644 --- a/examples/voice/voice-sarvam-http.py +++ b/examples/voice/voice-sarvam-http.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -97,7 +97,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -113,16 +113,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-sarvam.py b/examples/voice/voice-sarvam.py index 5c646d505..f44d0ae28 100644 --- a/examples/voice/voice-sarvam.py +++ b/examples/voice/voice-sarvam.py @@ -13,7 +13,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -91,7 +91,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -106,20 +106,20 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) # Optionally, you can wait for 30 seconds and then change the voice. # await asyncio.sleep(30) - # await task.queue_frame(TTSUpdateSettingsFrame(settings={"voice": "anushka"})) + # await worker.queue_frame(TTSUpdateSettingsFrame(settings={"voice": "anushka"})) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-smallest.py b/examples/voice/voice-smallest.py index b5b82802a..3ad28323b 100644 --- a/examples/voice/voice-smallest.py +++ b/examples/voice/voice-smallest.py @@ -13,7 +13,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -90,7 +90,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -102,16 +102,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): async def on_client_connected(transport, client): logger.info(f"Client connected") context.add_message({"role": "user", "content": "Please introduce yourself to the user."}) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-soniox.py b/examples/voice/voice-soniox.py index 0ad8b166c..842cb716d 100644 --- a/examples/voice/voice-soniox.py +++ b/examples/voice/voice-soniox.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -93,7 +93,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): assistant_aggregator, # Assistant spoken responses ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -109,16 +109,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-speechmatics-vad.py b/examples/voice/voice-speechmatics-vad.py index b21bf7156..fe208ad7b 100644 --- a/examples/voice/voice-speechmatics-vad.py +++ b/examples/voice/voice-speechmatics-vad.py @@ -13,7 +13,7 @@ from loguru import logger from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -135,7 +135,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -149,16 +149,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): logger.info(f"Client connected") # Kick off the conversation. context.add_message({"role": "developer", "content": "Say a short hello to the user."}) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-speechmatics.py b/examples/voice/voice-speechmatics.py index 3f7fa9ac4..2240eaf8c 100644 --- a/examples/voice/voice-speechmatics.py +++ b/examples/voice/voice-speechmatics.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -115,7 +115,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -129,16 +129,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): logger.info(f"Client connected") # Kick off the conversation. context.add_message({"role": "developer", "content": "Say a short hello to the user."}) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-xai-http.py b/examples/voice/voice-xai-http.py index 6d0d54e79..d07188946 100644 --- a/examples/voice/voice-xai-http.py +++ b/examples/voice/voice-xai-http.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -88,7 +88,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -104,16 +104,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-xai.py b/examples/voice/voice-xai.py index 541d66c77..89d88ae86 100644 --- a/examples/voice/voice-xai.py +++ b/examples/voice/voice-xai.py @@ -14,7 +14,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -88,7 +88,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -104,16 +104,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/examples/voice/voice-xtts.py b/examples/voice/voice-xtts.py index f9d92e45b..f5507aa95 100644 --- a/examples/voice/voice-xtts.py +++ b/examples/voice/voice-xtts.py @@ -15,7 +15,7 @@ from pipecat.audio.vad.silero import SileroVADAnalyzer from pipecat.frames.frames import LLMRunFrame from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.aggregators.llm_response_universal import ( LLMContextAggregatorPair, @@ -90,7 +90,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): ] ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_metrics=True, @@ -106,16 +106,16 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments): context.add_message( {"role": "developer", "content": "Please introduce yourself to the user."} ) - await task.queue_frames([LLMRunFrame()]) + await worker.queue_frames([LLMRunFrame()]) @transport.event_handler("on_client_disconnected") async def on_client_disconnected(transport, client): logger.info(f"Client disconnected") - await task.cancel() + await worker.cancel() runner = PipelineRunner(handle_sigint=runner_args.handle_sigint) - await runner.run(task) + await runner.run(worker) async def bot(runner_args: RunnerArguments): diff --git a/src/pipecat/bus/__init__.py b/src/pipecat/bus/__init__.py index 513f9f2a1..284a3949f 100644 --- a/src/pipecat/bus/__init__.py +++ b/src/pipecat/bus/__init__.py @@ -4,33 +4,33 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""Task bus package -- pub/sub messaging between tasks and the runner. +"""Worker bus package -- pub/sub messaging between workers and the runner. -Provides the pub/sub infrastructure that connects tasks to each other and to +Provides the pub/sub infrastructure that connects workers to each other and to the runner. Key components: -- `TaskBus` -- abstract base class defining the send/receive interface. +- `WorkerBus` -- abstract base class defining the send/receive interface. - `AsyncQueueBus` -- in-process implementation backed by ``asyncio.Queue``. - `BusBridgeProcessor` -- bidirectional mid-pipeline bridge for - transport/session tasks that exchanges frames with other tasks + transport/session workers that exchanges frames with other workers through the bus. - `BusMessage` and its subclasses -- the typed message hierarchy used for - task lifecycle events (activation, cancellation, shutdown), job + worker lifecycle events (activation, cancellation, shutdown), job coordination, and frame transport. """ from pipecat.bus.bridge_processor import BusBridgeProcessor -from pipecat.bus.bus import TaskBus +from pipecat.bus.bus import WorkerBus from pipecat.bus.local import AsyncQueueBus from pipecat.bus.messages import ( - BusActivateTaskMessage, - BusAddTaskMessage, + BusActivateWorkerMessage, + BusAddWorkerMessage, BusCancelMessage, - BusCancelTaskMessage, + BusCancelWorkerMessage, BusDataMessage, - BusDeactivateTaskMessage, + BusDeactivateWorkerMessage, BusEndMessage, - BusEndTaskMessage, + BusEndWorkerMessage, BusFrameMessage, BusJobCancelMessage, BusJobRequestMessage, @@ -45,29 +45,29 @@ from pipecat.bus.messages import ( BusLocalMessage, BusMessage, BusSystemMessage, - BusTaskErrorMessage, - BusTaskLocalErrorMessage, - BusTaskReadyMessage, - BusTaskRegistryMessage, + BusWorkerErrorMessage, + BusWorkerLocalErrorMessage, + BusWorkerReadyMessage, + BusWorkerRegistryMessage, ) from pipecat.bus.subscriber import BusSubscriber -from pipecat.registry.types import TaskRegistryEntry +from pipecat.registry.types import WorkerRegistryEntry __all__ = [ - "TaskBus", + "WorkerBus", "AsyncQueueBus", - "BusActivateTaskMessage", - "BusAddTaskMessage", - "BusTaskErrorMessage", - "BusTaskLocalErrorMessage", - "TaskRegistryEntry", - "BusTaskReadyMessage", - "BusTaskRegistryMessage", + "BusActivateWorkerMessage", + "BusAddWorkerMessage", + "BusWorkerErrorMessage", + "BusWorkerLocalErrorMessage", + "WorkerRegistryEntry", + "BusWorkerReadyMessage", + "BusWorkerRegistryMessage", "BusBridgeProcessor", - "BusCancelTaskMessage", + "BusCancelWorkerMessage", "BusCancelMessage", - "BusDeactivateTaskMessage", - "BusEndTaskMessage", + "BusDeactivateWorkerMessage", + "BusEndWorkerMessage", "BusEndMessage", "BusFrameMessage", "BusDataMessage", diff --git a/src/pipecat/bus/bridge_processor.py b/src/pipecat/bus/bridge_processor.py index b296cae3c..6f0250f8f 100644 --- a/src/pipecat/bus/bridge_processor.py +++ b/src/pipecat/bus/bridge_processor.py @@ -4,21 +4,21 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""Bus bridge and edge processors for inter-task frame routing. +"""Bus bridge and edge processors for inter-worker frame routing. Provides: - `BusBridgeProcessor`: a mid-pipeline processor that exchanges frames - with other tasks through the bus, consuming local frames. + with other workers through the bus, consuming local frames. - `_BusEdgeProcessor`: a pipeline-edge processor used internally by - `PipelineTask` when ``bridged`` is set. Tees frames between the local + `PipelineWorker` when ``bridged`` is set. Tees frames between the local pipeline and the bus (frames continue locally and are also forwarded to the bus). """ from typing import TYPE_CHECKING -from pipecat.bus.bus import TaskBus +from pipecat.bus.bus import WorkerBus from pipecat.bus.messages import BusFrameMessage, BusMessage from pipecat.bus.subscriber import BusSubscriber from pipecat.frames.frames import ( @@ -32,7 +32,7 @@ from pipecat.frames.frames import ( from pipecat.processors.frame_processor import FrameDirection, FrameProcessor, FrameProcessorSetup if TYPE_CHECKING: - from pipecat.pipeline.base_task import BaseTask + from pipecat.pipeline.base_worker import BaseWorker _LIFECYCLE_FRAMES = (StartFrame, EndFrame, CancelFrame, StopFrame) _PASSTHROUGH_FRAMES = (OutputTransportMessageUrgentFrame,) @@ -41,16 +41,16 @@ _PASSTHROUGH_FRAMES = (OutputTransportMessageUrgentFrame,) class BusBridgeProcessor(FrameProcessor, BusSubscriber): """Bidirectional mid-pipeline bridge between a Pipecat pipeline and the bus. - Placed in a transport or session task's pipeline to exchange frames - with other tasks via the `TaskBus`. Lifecycle and excluded frames + Placed in a transport or session worker's pipeline to exchange frames + with other workers via the `WorkerBus`. Lifecycle and excluded frames pass through locally without crossing the bus. """ def __init__( self, *, - bus: TaskBus, - task_name: str, + bus: WorkerBus, + worker_name: str, target_task: str | None = None, bridge: str | None = None, exclude_frames: tuple[type[Frame], ...] | None = None, @@ -59,9 +59,9 @@ class BusBridgeProcessor(FrameProcessor, BusSubscriber): """Initialize the BusBridgeProcessor. Args: - bus: The `TaskBus` to exchange frames with. - task_name: Name of the owning task, used as message source. - target_task: When set, only exchange frames with this task. + bus: The `WorkerBus` to exchange frames with. + worker_name: Name of the owning worker, used as message source. + target_task: When set, only exchange frames with this worker. bridge: Optional bridge name for routing. When set, outgoing frames are tagged with this name and only incoming frames with the same bridge name are accepted. @@ -71,7 +71,7 @@ class BusBridgeProcessor(FrameProcessor, BusSubscriber): """ super().__init__(**kwargs) self._bus = bus - self._task_name = task_name + self._worker_name = worker_name self._target_task = target_task self._bridge = bridge self._exclude_frames = exclude_frames or () @@ -101,7 +101,7 @@ class BusBridgeProcessor(FrameProcessor, BusSubscriber): return # Urgent transport frames pass through directly. They need to - # reach the transport even when no child task is active yet. + # reach the transport even when no child worker is active yet. if isinstance(frame, _PASSTHROUGH_FRAMES): await self.push_frame(frame, direction) return @@ -113,7 +113,7 @@ class BusBridgeProcessor(FrameProcessor, BusSubscriber): # Send to bus msg = BusFrameMessage( - source=self._task_name, + source=self._worker_name, frame=frame, direction=direction, bridge=self._bridge, @@ -130,19 +130,19 @@ class BusBridgeProcessor(FrameProcessor, BusSubscriber): return # Skip own frames - if message.source == self._task_name: + if message.source == self._worker_name: return # Filter by bridge name if self._bridge and message.bridge != self._bridge: return - # If target_task set, only accept from that task + # If target_task set, only accept from that worker if self._target_task and message.source != self._target_task: return # If message targeted at someone else, skip - if message.target and message.target != self._task_name: + if message.target and message.target != self._worker_name: return await self.push_frame(message.frame, message.direction) @@ -151,7 +151,7 @@ class BusBridgeProcessor(FrameProcessor, BusSubscriber): class _BusEdgeProcessor(FrameProcessor, BusSubscriber): """Pipeline-edge tee between a local pipeline and the bus. - Placed by `PipelineTask` at the source and sink of a bridged + Placed by `PipelineWorker` at the source and sink of a bridged pipeline. Frames always continue through the local pipeline; in addition, frames travelling in ``direction`` are forwarded to the bus, and frames received from the bus in the opposite direction @@ -161,7 +161,7 @@ class _BusEdgeProcessor(FrameProcessor, BusSubscriber): def __init__( self, *, - task: "BaseTask", + worker: "BaseWorker", direction: FrameDirection, bridges: tuple[str, ...] = (), exclude_frames: tuple[type[Frame], ...] | None = None, @@ -170,11 +170,11 @@ class _BusEdgeProcessor(FrameProcessor, BusSubscriber): """Initialize the edge processor. Args: - task: The owning task; the edge reads ``task.bus`` lazily + worker: The owning worker; the edge reads ``worker.bus`` lazily so the bus only needs to be set (via - :meth:`BaseTask.attach`) by the time the processor is - set up. ``task.name`` is the message source and - ``task.active`` gates inbound frames. + :meth:`BaseWorker.attach`) by the time the processor is + set up. ``worker.name`` is the message source and + ``worker.active`` gates inbound frames. direction: Direction this edge captures and forwards to the bus. Inbound frames from the bus travelling in the opposite direction are injected here. @@ -185,7 +185,7 @@ class _BusEdgeProcessor(FrameProcessor, BusSubscriber): **kwargs: Additional arguments passed to ``FrameProcessor``. """ super().__init__(**kwargs) - self._task = task + self._task = worker self._direction = direction self._bridges = bridges self._exclude_frames = exclude_frames or () diff --git a/src/pipecat/bus/bus.py b/src/pipecat/bus/bus.py index 14bb2a084..009419cdb 100644 --- a/src/pipecat/bus/bus.py +++ b/src/pipecat/bus/bus.py @@ -4,9 +4,9 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""Abstract task bus for inter-task pub/sub messaging. +"""Abstract worker bus for inter-worker pub/sub messaging. -Provides the abstract `TaskBus` base class. Concrete implementations +Provides the abstract `WorkerBus` base class. Concrete implementations (e.g. `AsyncQueueBus`) live in separate modules. """ @@ -30,7 +30,7 @@ class BusSubscription: subscriber: The subscriber receiving messages. queue: Priority queue for incoming messages. data_queue: Secondary queue for data messages dispatched by - the router task. + the router worker. router_task: Task that reads from the priority queue, handles system messages inline, and routes data messages to the data queue. @@ -45,8 +45,8 @@ class BusSubscription: data_task: asyncio.Task | None = field(default=None, repr=False) -class TaskBus(BaseObject): - """Abstract base for inter-task and runner-task communication. +class WorkerBus(BaseObject): + """Abstract base for inter-worker and runner-worker communication. Provides pub/sub messaging where each subscriber receives messages independently through its own priority queue. System messages @@ -60,7 +60,7 @@ class TaskBus(BaseObject): """ def __init__(self, **kwargs): - """Initialize the TaskBus. + """Initialize the WorkerBus. Args: **kwargs: Additional arguments passed to `BaseObject`. @@ -101,7 +101,7 @@ class TaskBus(BaseObject): sub = BusSubscription(subscriber=subscriber) if self._running: self._start_dispatch_task(sub) - # Schedule task right away. + # Schedule worker right away. await asyncio.sleep(0) if subscriber.name in self._subscriptions: raise ValueError(f"Subscriber '{subscriber.name}' is already registered on the bus") diff --git a/src/pipecat/bus/local/async_queue.py b/src/pipecat/bus/local/async_queue.py index bc3cbd3a8..09721919c 100644 --- a/src/pipecat/bus/local/async_queue.py +++ b/src/pipecat/bus/local/async_queue.py @@ -4,15 +4,15 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""In-process task bus backed by asyncio queues.""" +"""In-process worker bus backed by asyncio queues.""" from loguru import logger -from pipecat.bus.bus import TaskBus +from pipecat.bus.bus import WorkerBus from pipecat.bus.messages import BusMessage -class AsyncQueueBus(TaskBus): +class AsyncQueueBus(WorkerBus): """In-process bus that delivers messages via priority queues.""" async def publish(self, message: BusMessage) -> None: diff --git a/src/pipecat/bus/messages.py b/src/pipecat/bus/messages.py index 973819644..3ed32eac6 100644 --- a/src/pipecat/bus/messages.py +++ b/src/pipecat/bus/messages.py @@ -4,10 +4,10 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""Bus message types for inter-task communication. +"""Bus message types for inter-worker communication. -Defines the message hierarchy used by the `TaskBus` for pub/sub messaging -between tasks, the session, and the runner. +Defines the message hierarchy used by the `WorkerBus` for pub/sub messaging +between workers and the runner. """ from __future__ import annotations @@ -17,10 +17,10 @@ from typing import TYPE_CHECKING from pipecat.frames.frames import DataFrame, Frame, SystemFrame from pipecat.processors.frame_processor import FrameDirection -from pipecat.registry.types import TaskRegistryEntry +from pipecat.registry.types import WorkerRegistryEntry if TYPE_CHECKING: - from pipecat.pipeline.base_task import BaseTask + from pipecat.pipeline.base_worker import BaseWorker from pipecat.pipeline.job_context import JobStatus # --------------------------------------------------------------------------- @@ -53,8 +53,8 @@ class BusDataMessage(BusMessage, DataFrame): """Normal-priority bus message. Parameters: - source: Name of the task or component that sent this message. - target: Name of the intended recipient task, or None for broadcast. + source: Name of the worker or component that sent this message. + target: Name of the intended recipient worker, or None for broadcast. """ source: str @@ -66,8 +66,8 @@ class BusSystemMessage(BusMessage, SystemFrame): """High-priority bus message that preempts normal messages in subscriber queues. Parameters: - source: Name of the task or component that sent this message. - target: Name of the intended recipient task, or None for broadcast. + source: Name of the worker or component that sent this message. + target: Name of the intended recipient worker, or None for broadcast. """ source: str @@ -95,13 +95,13 @@ class BusFrameMessage(BusDataMessage): # --------------------------------------------------------------------------- -# Task lifecycle +# Worker lifecycle # --------------------------------------------------------------------------- @dataclass -class BusActivateTaskMessage(BusDataMessage): - """Tells a targeted task to become active and start processing. +class BusActivateWorkerMessage(BusDataMessage): + """Tells a targeted worker to become active and start processing. Parameters: args: Optional activation arguments forwarded to `on_activated`. @@ -111,8 +111,8 @@ class BusActivateTaskMessage(BusDataMessage): @dataclass -class BusDeactivateTaskMessage(BusDataMessage): - """Tells a targeted task to become inactive and stop processing.""" +class BusDeactivateWorkerMessage(BusDataMessage): + """Tells a targeted worker to become inactive and stop processing.""" pass @@ -121,8 +121,8 @@ class BusDeactivateTaskMessage(BusDataMessage): class BusEndMessage(BusDataMessage): """Request a graceful end of the session. - Sent by a task to the runner, which responds by sending - `BusEndTaskMessage` to each task. + Sent by a worker to the runner, which responds by sending + `BusEndWorkerMessage` to each worker. Parameters: reason: Optional human-readable reason for ending. @@ -132,10 +132,10 @@ class BusEndMessage(BusDataMessage): @dataclass -class BusEndTaskMessage(BusDataMessage): - """Tells a targeted task to end its pipeline gracefully. +class BusEndWorkerMessage(BusDataMessage): + """Tells a targeted worker to end its pipeline gracefully. - Sent by the runner to individual tasks during shutdown. + Sent by the runner to individual workers during shutdown. Parameters: reason: Optional human-readable reason for ending. @@ -148,8 +148,8 @@ class BusEndTaskMessage(BusDataMessage): class BusCancelMessage(BusSystemMessage): """Request a hard cancel of the session. - Sent by a task to the runner, which responds by sending - `BusCancelTaskMessage` to each task. + Sent by a worker to the runner, which responds by sending + `BusCancelWorkerMessage` to each worker. Parameters: reason: Optional human-readable reason for the cancellation. @@ -159,10 +159,10 @@ class BusCancelMessage(BusSystemMessage): @dataclass -class BusCancelTaskMessage(BusSystemMessage): - """Tells a targeted task to cancel its pipeline. +class BusCancelWorkerMessage(BusSystemMessage): + """Tells a targeted worker to cancel its pipeline. - Sent by the runner to individual tasks during cancellation. + Sent by the runner to individual workers during cancellation. Parameters: reason: Optional human-readable reason for the cancellation. @@ -172,54 +172,54 @@ class BusCancelTaskMessage(BusSystemMessage): # --------------------------------------------------------------------------- -# Task registry and errors +# Worker registry and errors # --------------------------------------------------------------------------- @dataclass -class BusAddTaskMessage(BusSystemMessage, BusLocalMessage): - """Request to add a task to the local runner. +class BusAddWorkerMessage(BusSystemMessage, BusLocalMessage): + """Request to add a worker to the local runner. - Local-only: carries an in-memory task reference that cannot be + Local-only: carries an in-memory worker reference that cannot be serialized over the network. Parameters: - task: The task instance to add. + worker: The worker instance to add. """ - task: BaseTask + worker: BaseWorker @dataclass -class BusTaskRegistryMessage(BusSystemMessage): - """Snapshot of tasks managed by a runner. +class BusWorkerRegistryMessage(BusSystemMessage): + """Snapshot of workers managed by a runner. Sent by the runner on startup and when new runners connect, - so that remote runners can discover each other's tasks. + so that remote runners can discover each other's workers. Parameters: - runner: Name of the runner that owns these tasks. - tasks: List of task entries with their state. + runner: Name of the runner that owns these workers. + workers: List of worker entries with their state. """ runner: str - tasks: list[TaskRegistryEntry] + workers: list[WorkerRegistryEntry] @dataclass -class BusTaskReadyMessage(BusDataMessage): - """Announces that a task is ready. +class BusWorkerReadyMessage(BusDataMessage): + """Announces that a worker is ready. - Sent when any task (root or child) becomes ready. Carries the - task's parent name so observers can reconstruct the full hierarchy. + Sent when any worker (root or child) becomes ready. Carries the + worker's parent name so observers can reconstruct the full hierarchy. Parameters: - runner: Name of the runner managing this task. - parent: Name of the parent task, or None for root tasks. - active: Whether the task started active. - bridged: Whether the task is bridged (receives pipeline frames + runner: Name of the runner managing this worker. + parent: Name of the parent worker, or None for root workers. + active: Whether the worker started active. + bridged: Whether the worker is bridged (receives pipeline frames from the bus). - started_at: Unix timestamp when the task became ready. + started_at: Unix timestamp when the worker became ready. """ runner: str @@ -230,11 +230,11 @@ class BusTaskReadyMessage(BusDataMessage): @dataclass -class BusTaskErrorMessage(BusSystemMessage): - """Reports an error from a root task. +class BusWorkerErrorMessage(BusSystemMessage): + """Reports an error from a root worker. - Sent over the network so remote tasks can react. For child task - errors, see `BusTaskLocalErrorMessage`. + Sent over the network so remote workers can react. For child worker + errors, see `BusWorkerLocalErrorMessage`. Parameters: error: Description of the error. @@ -244,11 +244,11 @@ class BusTaskErrorMessage(BusSystemMessage): @dataclass -class BusTaskLocalErrorMessage(BusSystemMessage, BusLocalMessage): - """Reports an error from a child task to its parent. +class BusWorkerLocalErrorMessage(BusSystemMessage, BusLocalMessage): + """Reports an error from a child worker to its parent. Local-only: never crosses the network. The parent receives it - via `on_task_failed()`. + via `on_worker_failed()`. Parameters: error: Description of the error. @@ -264,7 +264,7 @@ class BusTaskLocalErrorMessage(BusSystemMessage, BusLocalMessage): @dataclass class BusJobRequestMessage(BusDataMessage): - """Requests a worker task to start work. + """Requests a worker worker to start work. Parameters: job_id: Unique identifier for this job. @@ -279,7 +279,7 @@ class BusJobRequestMessage(BusDataMessage): @dataclass class BusJobResponseMessage(BusDataMessage): - """Response from a worker task when its job completes. + """Response from a worker worker when its job completes. Parameters: job_id: The job identifier. @@ -312,7 +312,7 @@ class BusJobResponseUrgentMessage(BusSystemMessage): @dataclass class BusJobUpdateMessage(BusDataMessage): - """Progress update from a worker task. + """Progress update from a worker worker. Parameters: job_id: The job identifier. @@ -341,7 +341,7 @@ class BusJobUpdateUrgentMessage(BusSystemMessage): @dataclass class BusJobUpdateRequestMessage(BusDataMessage): - """Request a progress update from a worker task. + """Request a progress update from a worker worker. Parameters: job_id: The job identifier. diff --git a/src/pipecat/bus/network/__init__.py b/src/pipecat/bus/network/__init__.py index 4ff4848a2..9824c0e6f 100644 --- a/src/pipecat/bus/network/__init__.py +++ b/src/pipecat/bus/network/__init__.py @@ -4,7 +4,7 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""Network bus implementations for distributed tasks. +"""Network bus implementations for distributed workers. Each adapter has its own optional dependency. Imports are lazy so the package can be loaded with only the extras you need; importing a specific diff --git a/src/pipecat/bus/network/pgmq.py b/src/pipecat/bus/network/pgmq.py index 2ec369599..dc6697f2a 100644 --- a/src/pipecat/bus/network/pgmq.py +++ b/src/pipecat/bus/network/pgmq.py @@ -4,14 +4,14 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""PGMQ (PostgreSQL Message Queue) task bus for distributed tasks.""" +"""PGMQ (PostgreSQL Message Queue) worker bus for distributed workers.""" import asyncio import json from loguru import logger -from pipecat.bus.bus import TaskBus +from pipecat.bus.bus import WorkerBus from pipecat.bus.messages import BusMessage from pipecat.bus.network.pgmq_backends import ( DirectPgmqBackend, @@ -28,8 +28,8 @@ except ModuleNotFoundError as e: # pragma: no cover - exercised only when extra raise Exception(f"Missing module: {e}") -class PgmqBus(TaskBus): - """Distributed task bus backed by PGMQ (PostgreSQL Message Queue). +class PgmqBus(WorkerBus): + """Distributed worker bus backed by PGMQ (PostgreSQL Message Queue). Pub/sub fan-out is implemented on top of PGMQ's point-to-point queue semantics by giving each :class:`PgmqBus` instance its own queue and @@ -113,7 +113,7 @@ class PgmqBus(TaskBus): this knob.) max_poll_seconds: Maximum seconds the reader blocks per poll cycle. Defaults to 5. - **kwargs: Additional arguments passed to :class:`TaskBus`. + **kwargs: Additional arguments passed to :class:`WorkerBus`. """ super().__init__(**kwargs) if pgmq is not None and backend is not None: diff --git a/src/pipecat/bus/network/redis.py b/src/pipecat/bus/network/redis.py index 781660a9d..e0d8d56ac 100644 --- a/src/pipecat/bus/network/redis.py +++ b/src/pipecat/bus/network/redis.py @@ -4,13 +4,13 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""Redis pub/sub task bus for distributed tasks.""" +"""Redis pub/sub worker bus for distributed workers.""" import asyncio from loguru import logger -from pipecat.bus.bus import TaskBus +from pipecat.bus.bus import WorkerBus from pipecat.bus.messages import BusMessage from pipecat.bus.serializers import JSONMessageSerializer from pipecat.bus.serializers.base import MessageSerializer @@ -24,8 +24,8 @@ except ModuleNotFoundError as e: raise Exception(f"Missing module: {e}") -class RedisBus(TaskBus): - """Distributed task bus backed by Redis pub/sub. +class RedisBus(WorkerBus): + """Distributed worker bus backed by Redis pub/sub. Publishes serialized messages to a Redis channel for cross-process communication. ``BusLocalMessage`` messages bypass Redis and are @@ -56,7 +56,7 @@ class RedisBus(TaskBus): serializer: The `MessageSerializer` for encoding/decoding messages. Defaults to `JSONMessageSerializer`. channel: The Redis pub/sub channel name. Defaults to ``"pipecat:bus"``. - **kwargs: Additional arguments passed to `TaskBus`. + **kwargs: Additional arguments passed to `WorkerBus`. """ super().__init__(**kwargs) self._redis = redis diff --git a/src/pipecat/bus/subscriber.py b/src/pipecat/bus/subscriber.py index fdb513396..ec81f90a6 100644 --- a/src/pipecat/bus/subscriber.py +++ b/src/pipecat/bus/subscriber.py @@ -4,13 +4,13 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""Bus subscriber mixin for receiving messages from an TaskBus.""" +"""Bus subscriber mixin for receiving messages from an WorkerBus.""" from pipecat.bus.messages import BusMessage class BusSubscriber: - """Mixin for objects that receive messages from an `TaskBus`. + """Mixin for objects that receive messages from an `WorkerBus`. Implementors override `on_bus_message()` to handle incoming messages. Concrete subscribers must provide a ``name`` property (typically diff --git a/src/pipecat/extensions/voicemail/voicemail_detector.py b/src/pipecat/extensions/voicemail/voicemail_detector.py index d7e9d559b..5886664d4 100644 --- a/src/pipecat/extensions/voicemail/voicemail_detector.py +++ b/src/pipecat/extensions/voicemail/voicemail_detector.py @@ -59,16 +59,16 @@ class NotifierGate(FrameProcessor): decisions or events. """ - def __init__(self, notifier: BaseNotifier, task_name: str = "gate"): + def __init__(self, notifier: BaseNotifier, worker_name: str = "gate"): """Initialize the notifier gate. Args: notifier: Notifier that signals when the gate should close. - task_name: Name for the notification waiting task (for debugging). + worker_name: Name for the notification waiting task (for debugging). """ super().__init__() self._notifier = notifier - self._task_name = task_name + self._worker_name = worker_name self._gate_opened = True self._gate_task: asyncio.Task | None = None @@ -139,7 +139,7 @@ class ClassifierGate(NotifierGate): been made and the gate should close. conversation_notifier: Notifier that signals when conversation is detected. """ - super().__init__(gate_notifier, task_name="classifier_gate") + super().__init__(gate_notifier, worker_name="classifier_gate") self._conversation_notifier = conversation_notifier self._conversation_detected = False self._conversation_task: asyncio.Task | None = None @@ -208,7 +208,7 @@ class ConversationGate(NotifierGate): voicemail_notifier: Notifier that signals when voicemail has been detected and the conversation should be blocked. """ - super().__init__(voicemail_notifier, task_name="conversation_gate") + super().__init__(voicemail_notifier, worker_name="conversation_gate") class ClassificationProcessor(FrameProcessor): diff --git a/src/pipecat/observers/startup_timing_observer.py b/src/pipecat/observers/startup_timing_observer.py index ac63ab10a..87463289f 100644 --- a/src/pipecat/observers/startup_timing_observer.py +++ b/src/pipecat/observers/startup_timing_observer.py @@ -31,7 +31,7 @@ Example:: print(f"Bot connected in {report.bot_connected_secs:.3f}s") print(f"Client connected in {report.client_connected_secs:.3f}s") - task = PipelineTask(pipeline, observers=[observer]) + worker = PipelineWorker(pipeline, observers=[observer]) """ import time @@ -155,7 +155,7 @@ class StartupTimingObserver(BaseObserver): logger.info(f"Bot connected in {report.bot_connected_secs:.3f}s") logger.info(f"Client connected in {report.client_connected_secs:.3f}s") - task = PipelineTask(pipeline, observers=[observer]) + worker = PipelineWorker(pipeline, observers=[observer]) Args: processor_types: Optional tuple of processor types to measure. If None, @@ -216,7 +216,7 @@ class StartupTimingObserver(BaseObserver): async def on_pipeline_started(self): """Emit the startup timing report when the pipeline has fully started. - Called by the ``PipelineTask`` after the ``StartFrame`` has been + Called by the ``PipelineWorker`` after the ``StartFrame`` has been processed by all processors, including nested ``ParallelPipeline`` branches. """ diff --git a/src/pipecat/observers/user_bot_latency_observer.py b/src/pipecat/observers/user_bot_latency_observer.py index 5e4084406..793ef2cc1 100644 --- a/src/pipecat/observers/user_bot_latency_observer.py +++ b/src/pipecat/observers/user_bot_latency_observer.py @@ -85,7 +85,7 @@ class LatencyBreakdown(BaseModel): Collected between ``VADUserStoppedSpeakingFrame`` and ``BotStartedSpeakingFrame`` when ``enable_metrics=True`` in - :class:`~pipecat.pipeline.task.PipelineParams`. + :class:`~pipecat.pipeline.worker.PipelineParams`. Parameters: ttfb: Time-to-first-byte metrics from each service in the pipeline. diff --git a/src/pipecat/pipeline/base_task.py b/src/pipecat/pipeline/base_worker.py similarity index 68% rename from src/pipecat/pipeline/base_task.py rename to src/pipecat/pipeline/base_worker.py index 771329468..7e5441e0e 100644 --- a/src/pipecat/pipeline/base_task.py +++ b/src/pipecat/pipeline/base_worker.py @@ -4,10 +4,10 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""Abstract base task for the multi-task framework. +"""Abstract base worker for the multi-worker framework. -Provides the `BaseTask` class that all tasks inherit from, handling -task lifecycle, parent-child relationships, and long-running job +Provides the `BaseWorker` class that all workers inherit from, handling +worker lifecycle, parent-child relationships, and long-running job coordination on the bus. """ @@ -21,16 +21,16 @@ from typing import TYPE_CHECKING, Self from loguru import logger if TYPE_CHECKING: - from pipecat.pipeline.task import PipelineTaskParams + from pipecat.pipeline.worker import PipelineWorkerParams from pipecat.bus import ( - BusActivateTaskMessage, - BusAddTaskMessage, + BusActivateWorkerMessage, + BusAddWorkerMessage, BusCancelMessage, - BusCancelTaskMessage, - BusDeactivateTaskMessage, + BusCancelWorkerMessage, + BusDeactivateWorkerMessage, BusEndMessage, - BusEndTaskMessage, + BusEndWorkerMessage, BusJobCancelMessage, BusJobRequestMessage, BusJobResponseMessage, @@ -42,10 +42,10 @@ from pipecat.bus import ( BusJobUpdateRequestMessage, BusJobUpdateUrgentMessage, BusMessage, - BusTaskErrorMessage, - BusTaskLocalErrorMessage, - BusTaskReadyMessage, - TaskBus, + BusWorkerErrorMessage, + BusWorkerLocalErrorMessage, + BusWorkerReadyMessage, + WorkerBus, ) from pipecat.bus.messages import BusFrameMessage from pipecat.bus.subscriber import BusSubscriber @@ -59,16 +59,16 @@ from pipecat.pipeline.job_context import ( JobStatus, ) from pipecat.pipeline.job_decorator import _collect_job_handlers -from pipecat.pipeline.task_ready_decorator import _collect_task_ready_handlers -from pipecat.registry import TaskRegistry -from pipecat.registry.types import TaskErrorData, TaskReadyData +from pipecat.pipeline.worker_ready_decorator import _collect_worker_ready_handlers +from pipecat.registry import WorkerRegistry +from pipecat.registry.types import WorkerErrorData, WorkerReadyData from pipecat.utils.asyncio.task_manager import TaskManager, TaskManagerParams from pipecat.utils.base_object import BaseObject @dataclass -class TaskActivationArgs: - """Base activation arguments for any task. +class WorkerActivationArgs: + """Base activation arguments for any worker. Parameters: metadata: Optional structured data passed during activation. @@ -91,23 +91,23 @@ class TaskActivationArgs: } -class BaseTask(BaseObject, BusSubscriber): - """Abstract base for tasks in the multi-task framework. +class BaseWorker(BaseObject, BusSubscriber): + """Abstract base for workers in framework. - A task connects to a `TaskBus`, registers itself in the shared + A worker connects to a `WorkerBus`, registers itself in the shared registry, accepts activation/deactivation, and exchanges job - requests/responses with other tasks. Concrete subclasses - (e.g. `PipelineTask`) provide the runtime that actually drives - the task's work. + requests/responses with other workers. Concrete subclasses + (e.g. `PipelineWorker`) provide the runtime that actually drives + the worker's work. Overridable lifecycle methods (always call ``super()``): - - ``on_activated(args)``: Called when this task is activated. - - ``on_deactivated()``: Called when this task is deactivated. - - ``on_task_ready(data)``: Called when another task is ready - to receive messages. For local root tasks, fires automatically. - For children, fires only on the parent. For remote tasks, fires - only for tasks watched via ``watch_task()``. + - ``on_activated(args)``: Called when this worker is activated. + - ``on_deactivated()``: Called when this worker is deactivated. + - ``on_worker_ready(data)``: Called when another worker is ready + to receive messages. For local root workers, fires automatically. + For children, fires only on the parent. For remote workers, fires + only for workers watched via ``watch_worker()``. - ``on_job_request(message)``: Called when a job request is received. - ``on_job_response(message)``: Called when a worker sends a response. - ``on_job_update(message)``: Called when a worker sends a progress @@ -124,17 +124,17 @@ class BaseTask(BaseObject, BusSubscriber): a worker. - ``on_job_stream_end(message)``: Called when a worker finishes streaming. - - ``on_job_cancelled(message)``: Called when this task's job is + - ``on_job_cancelled(message)``: Called when this worker's job is cancelled by the requester. - ``on_bus_message(message)``: Called for bus messages after default lifecycle handling. Event handlers available: - - on_activated: Task was activated. - - on_deactivated: Task was deactivated. - - on_task_ready: Another task is ready. - - on_task_failed: A child task reported an error. + - on_activated: Worker was activated. + - on_deactivated: Worker was deactivated. + - on_worker_ready: Another worker is ready. + - on_worker_failed: A child worker reported an error. - on_job_request: Received a job request. - on_job_response: A worker sent a response. - on_job_update: A worker sent a progress update. @@ -144,7 +144,7 @@ class BaseTask(BaseObject, BusSubscriber): - on_job_stream_start: A worker started streaming. - on_job_stream_data: A worker sent a streaming chunk. - on_job_stream_end: A worker finished streaming. - - on_job_cancelled: This task's job was cancelled. + - on_job_cancelled: This worker's job was cancelled. - on_bus_message: A bus message was received. """ @@ -154,41 +154,41 @@ class BaseTask(BaseObject, BusSubscriber): *, active: bool = True, ): - """Initialize the BaseTask. + """Initialize the BaseWorker. Args: - name: Unique name for this task. If ``None``, an auto-generated + name: Unique name for this worker. If ``None``, an auto-generated name is used (useful for instances that don't participate - in inter-task communication). - active: Whether the task starts active. Defaults to True. + in inter-worker communication). + active: Whether the worker starts active. Defaults to True. """ super().__init__(name=name) # Runner-provided context. Populated by ``attach()`` before # ``run()`` is called. Accessing ``self.bus`` / ``self.registry`` # before ``attach()`` raises. - self._bus: TaskBus | None = None - self._registry: TaskRegistry | None = None + self._bus: WorkerBus | None = None + self._registry: WorkerRegistry | None = None - # Activation. Pending activation is deferred until the task + # Activation. Pending activation is deferred until the worker # starts, then on_activated fires. self._active = active self._pending_activation = active self._activation_args: dict | None = None - # Task lifecycle. Parent/children form a tree. Finished is set - # when the task stops. + # Worker lifecycle. Parent/children form a tree. Finished is set + # when the worker stops. self._parent: str | None = None - self._children: list[BaseTask] = [] + self._children: list[BaseWorker] = [] self._started_at: float | None = None self._finished_event: asyncio.Event = asyncio.Event() # Job coordination. Worker state tracks active job requests # keyed by job_id, supporting multiple jobs in flight # (e.g. parallel @job handlers). Each running handler has a - # tracked asyncio task so it can be cancelled by system + # tracked asyncio worker so it can be cancelled by system # messages. Requester state tracks job groups launched by - # this task. Job handlers are collected from @job decorated + # this worker. Job handlers are collected from @job decorated # methods at init. self._active_jobs: dict[str, BusJobRequestMessage] = {} self._job_handler_tasks: dict[str, asyncio.Task] = {} @@ -196,10 +196,10 @@ class BaseTask(BaseObject, BusSubscriber): self._job_handlers = _collect_job_handlers(self) self._job_locks: dict[str, asyncio.Lock] = {} - # Task-ready handlers collected from @task_ready decorated methods. - self._task_ready_handlers = _collect_task_ready_handlers(self) + # Worker-ready handlers collected from @worker_ready decorated methods. + self._worker_ready_handlers = _collect_worker_ready_handlers(self) - # Task lifecycle events + # Worker lifecycle events self._register_event_handler("on_activated") self._register_event_handler("on_deactivated") self._register_event_handler("on_bus_message") @@ -214,24 +214,24 @@ class BaseTask(BaseObject, BusSubscriber): self._register_event_handler("on_job_stream_end") self._register_event_handler("on_job_cancelled") - # Other tasks - self._register_event_handler("on_task_ready") - self._register_event_handler("on_task_failed") + # Other workers + self._register_event_handler("on_worker_ready") + self._register_event_handler("on_worker_failed") @property - def bus(self) -> TaskBus: - """The bus this task is attached to. + def bus(self) -> WorkerBus: + """The bus this worker is attached to. Raises: RuntimeError: If accessed before :meth:`attach` has been called. """ if self._bus is None: - raise RuntimeError(f"Task '{self}': bus is not set; call attach() first.") + raise RuntimeError(f"Worker '{self}': bus is not set; call attach() first.") return self._bus @property def active(self) -> bool: - """Whether this task is currently active.""" + """Whether this worker is currently active.""" return self._active @property @@ -241,83 +241,83 @@ class BaseTask(BaseObject, BusSubscriber): @property def parent(self) -> str | None: - """The name of the parent task, or None if this is a root task.""" + """The name of the parent worker, or None if this is a root worker.""" return self._parent @property - def registry(self) -> TaskRegistry: - """The shared task registry this task is attached to. + def registry(self) -> WorkerRegistry: + """The shared worker registry this worker is attached to. Raises: RuntimeError: If accessed before :meth:`attach` has been called. """ if self._registry is None: - raise RuntimeError(f"Task '{self}': registry is not set; call attach() first.") + raise RuntimeError(f"Worker '{self}': registry is not set; call attach() first.") return self._registry @property def started_at(self) -> float | None: - """Unix timestamp when this task became ready, or None if not yet started.""" + """Unix timestamp when this worker became ready, or None if not yet started.""" return self._started_at @property def bridged(self) -> bool: - """Whether this task is bridged onto the bus. + """Whether this worker is bridged onto the bus. - Subclasses (e.g. `PipelineTask`) override when they auto-wrap + Subclasses (e.g. `PipelineWorker`) override when they auto-wrap their pipeline with bus edge processors. """ return False @property - def children(self) -> list["BaseTask"]: - """The list of child tasks added via ``add_task()``.""" + def children(self) -> list["BaseWorker"]: + """The list of child workers added via ``add_worker()``.""" return self._children @property def active_jobs(self) -> dict[str, BusJobRequestMessage]: - """Active job requests this task is currently working on, keyed by job_id.""" + """Active job requests this worker is currently working on, keyed by job_id.""" return self._active_jobs @property def job_groups(self) -> dict[str, JobGroup]: - """Active job groups launched by this task, keyed by job_id.""" + """Active job groups launched by this worker, keyed by job_id.""" return self._job_groups - def attach(self, *, registry: TaskRegistry, bus: TaskBus) -> None: - """Attach the task to a runner-provided registry and bus. + def attach(self, *, registry: WorkerRegistry, bus: WorkerBus) -> None: + """Attach the worker to a runner-provided registry and bus. - Called by the runner (typically from ``spawn()``) before the - task is run. After this call, :attr:`registry` and :attr:`bus` + Called by the runner (typically from ``add_worker()``) before the + worker is run. After this call, :attr:`registry` and :attr:`bus` return the provided instances. Args: - registry: The shared task registry. - bus: The shared task bus. + registry: The shared worker registry. + bus: The shared worker bus. """ self._registry = registry self._bus = bus async def cleanup(self) -> None: - """Clean up the task and release resources. + """Clean up the worker and release resources. Cancels running jobs, unsubscribes from the bus, and signals - that the task has stopped. + that the worker has stopped. """ await super().cleanup() await self.stop() - async def run(self, params: "PipelineTaskParams") -> None: - """Run this task until it finishes. + async def run(self, params: "PipelineWorkerParams") -> None: + """Run this worker until it finishes. - The default implementation is for bus-only tasks: it subscribes - to the bus, marks the task as started, then waits until + The default implementation is for bus-only workers: it subscribes + to the bus, marks the worker as started, then waits until :meth:`stop` (or :meth:`_finished_event`) is signalled. Subclasses - with their own runtime (e.g. :class:`~pipecat.pipeline.task.PipelineTask`) + with their own runtime (e.g. :class:`~pipecat.pipeline.worker.PipelineWorker`) override this method. Args: - params: Configuration parameters for task execution. + params: Configuration parameters for worker execution. """ task_manager = TaskManager() task_manager.setup(TaskManagerParams(loop=params.loop)) @@ -335,21 +335,21 @@ class BaseTask(BaseObject, BusSubscriber): await self.stop() async def start(self) -> None: - """Mark the task as started, register, and activate if requested.""" + """Mark the worker as started, register, and activate if requested.""" self._started_at = time.time() await self._register_ready() await self._maybe_activate() - await self._watch_decorated_tasks() + await self._watch_decorated_workers() async def stop(self) -> None: - """Clean up and signal that this task has stopped. + """Clean up and signal that this worker has stopped. Cancels all running job groups and reports any still-active job requests back to their requesters as ``CANCELLED``, so parents aren't left waiting. """ for job_id in list(self._job_groups.keys()): - await self.cancel_job_group(job_id, reason=f"task '{self}' stopped") + await self.cancel_job_group(job_id, reason=f"worker '{self}' stopped") for job_id in list(self._active_jobs.keys()): await self.send_job_response(job_id, status=JobStatus.CANCELLED) self._finished_event.set() @@ -363,15 +363,15 @@ class BaseTask(BaseObject, BusSubscriber): await self.send_bus_message(BusEndMessage(source=self.name, reason=reason)) async def cancel(self) -> None: - """Request an immediate cancellation of all tasks.""" + """Request an immediate cancellation of all workers.""" await self.send_bus_message(BusCancelMessage(source=self.name)) async def wait(self) -> None: - """Wait for this task to finish.""" + """Wait for this worker to finish.""" await self._finished_event.wait() async def on_activated(self, args: dict | None) -> None: - """Called when this task is activated. + """Called when this worker is activated. Override in subclasses to react to activation. Always call ``super().on_activated(args)``. @@ -382,27 +382,27 @@ class BaseTask(BaseObject, BusSubscriber): pass async def on_deactivated(self) -> None: - """Called when this task is deactivated. + """Called when this worker is deactivated. Override in subclasses to react to deactivation. Always call ``super().on_deactivated()``. """ pass - async def on_task_ready(self, data: TaskReadyData) -> None: - """Called when another task is ready to receive messages. + async def on_worker_ready(self, data: WorkerReadyData) -> None: + """Called when another worker is ready to receive messages. - For local root tasks this fires automatically. For remote tasks - it fires only for tasks watched via ``watch_task()``. For child - tasks it fires only on the parent that created them. + For local root workers this fires automatically. For remote workers + it fires only for workers watched via ``watch_worker()``. For child + workers it fires only on the parent that created them. Args: - data: Information about the ready task. + data: Information about the ready worker. """ pass - async def on_task_failed(self, data: TaskErrorData) -> None: - """Called when a child task reports an error. + async def on_worker_failed(self, data: WorkerErrorData) -> None: + """Called when a child worker reports an error. Args: data: Information about the error. @@ -419,24 +419,24 @@ class BaseTask(BaseObject, BusSubscriber): Args: message: The `BusMessage` to process. """ - # Frame messages are not handled by the base task. + # Frame messages are not handled by the base worker. if isinstance(message, BusFrameMessage): return - # Ignore targeted messages for other tasks + # Ignore targeted messages for other workers if message.target and message.target != self.name: return - if isinstance(message, (BusTaskErrorMessage, BusTaskLocalErrorMessage)): - await self._handle_task_error(message) - elif isinstance(message, BusActivateTaskMessage): - await self._handle_task_activate(message) - elif isinstance(message, BusDeactivateTaskMessage): - await self._handle_task_deactivate(message) - elif isinstance(message, BusEndTaskMessage): - await self._handle_task_end(message) - elif isinstance(message, BusCancelTaskMessage): - await self._handle_task_cancel(message) + if isinstance(message, (BusWorkerErrorMessage, BusWorkerLocalErrorMessage)): + await self._handle_worker_error(message) + elif isinstance(message, BusActivateWorkerMessage): + await self._handle_worker_activate(message) + elif isinstance(message, BusDeactivateWorkerMessage): + await self._handle_worker_deactivate(message) + elif isinstance(message, BusEndWorkerMessage): + await self._handle_worker_end(message) + elif isinstance(message, BusCancelWorkerMessage): + await self._handle_worker_cancel(message) elif isinstance(message, BusJobRequestMessage): await self._handle_job_request(message) elif isinstance(message, (BusJobResponseMessage, BusJobResponseUrgentMessage)): @@ -457,7 +457,7 @@ class BaseTask(BaseObject, BusSubscriber): await self._call_event_handler("on_bus_message", message) async def on_job_request(self, message: BusJobRequestMessage) -> None: - """Called when this task receives a job request. + """Called when this worker receives a job request. Override to perform work. Use ``send_job_update()`` to report progress and ``send_job_response()`` to return results. @@ -514,7 +514,7 @@ class BaseTask(BaseObject, BusSubscriber): pass async def on_job_cancelled(self, message: BusJobCancelMessage) -> None: - """Called when this task's job is cancelled by the requester. + """Called when this worker's job is cancelled by the requester. Override to clean up resources or stop in-progress work. """ @@ -532,102 +532,104 @@ class BaseTask(BaseObject, BusSubscriber): async def send_bus_error_message(self, error: str) -> None: """Report an error on the bus. - Child tasks send a local-only message to the parent. - Root tasks broadcast over the network. + Child workers send a local-only message to the parent. + Root workers broadcast over the network. Args: error: Description of the error. """ if self._parent: - await self.send_bus_message(BusTaskLocalErrorMessage(source=self.name, error=error)) + await self.send_bus_message(BusWorkerLocalErrorMessage(source=self.name, error=error)) else: - await self.send_bus_message(BusTaskErrorMessage(source=self.name, error=error)) + await self.send_bus_message(BusWorkerErrorMessage(source=self.name, error=error)) - async def add_task(self, task: "BaseTask") -> None: - """Register a child task under this parent. + async def add_worker(self, worker: "BaseWorker") -> None: + """Register a child worker under this parent. The child's lifecycle (end, cancel) is automatically managed - by this parent task. To receive ``on_task_ready`` when the - child starts, call ``watch_task(task.name)``. + by this parent worker. To receive ``on_worker_ready`` when the + child starts, call ``watch_worker(worker.name)``. Args: - task: The child `BaseTask` instance to add. + worker: The child `BaseWorker` instance to add. """ - if task._parent is not None: - logger.error(f"Task '{task.name}' already has parent '{task._parent}', skipping") + if worker._parent is not None: + logger.error(f"Worker '{worker.name}' already has parent '{worker._parent}', skipping") return - task._parent = self.name - self._children.append(task) - await self.send_bus_message(BusAddTaskMessage(source=self.name, task=task)) + worker._parent = self.name + self._children.append(worker) + await self.send_bus_message(BusAddWorkerMessage(source=self.name, worker=worker)) - async def activate_task( + async def activate_worker( self, - task_name: str, + worker_name: str, *, - args: TaskActivationArgs | None = None, + args: WorkerActivationArgs | None = None, deactivate_self: bool = False, ) -> None: - """Activate a task by name. + """Activate a worker by name. - The target task's ``on_activated`` hook will be called + The target worker's ``on_activated`` hook will be called with the provided arguments. Args: - task_name: The name of the task to activate. - args: Optional ``TaskActivationArgs`` forwarded to the - target task's ``on_activated``. - deactivate_self: Whether to deactivate this task before activating + worker_name: The name of the worker to activate. + args: Optional ``WorkerActivationArgs`` forwarded to the + target worker's ``on_activated``. + deactivate_self: Whether to deactivate this worker before activating the target. """ if self._active and deactivate_self: - await self.deactivate_task(self.name) + await self.deactivate_worker(self.name) await self.send_bus_message( - BusActivateTaskMessage( - source=self.name, target=task_name, args=args.to_dict() if args else None + BusActivateWorkerMessage( + source=self.name, target=worker_name, args=args.to_dict() if args else None ) ) - async def deactivate_task(self, task_name: str) -> None: - """Deactivate a task by name. + async def deactivate_worker(self, worker_name: str) -> None: + """Deactivate a worker by name. - The target task's ``on_deactivated`` hook will be called. + The target worker's ``on_deactivated`` hook will be called. Args: - task_name: The name of the task to deactivate. + worker_name: The name of the worker to deactivate. """ - await self.send_bus_message(BusDeactivateTaskMessage(source=self.name, target=task_name)) + await self.send_bus_message( + BusDeactivateWorkerMessage(source=self.name, target=worker_name) + ) - async def watch_task(self, task_name: str) -> None: - """Request notification when a task registers. + async def watch_worker(self, worker_name: str) -> None: + """Request notification when a worker registers. - If the task is already registered, ``on_task_ready`` fires - immediately. Otherwise ``on_task_ready`` fires when the - task eventually registers. + If the worker is already registered, ``on_worker_ready`` fires + immediately. Otherwise ``on_worker_ready`` fires when the + worker eventually registers. Args: - task_name: The name of the task to watch for. + worker_name: The name of the worker to watch for. """ if self._registry: - logger.debug(f"Task '{self}': watching for task '{task_name}'") - await self._registry.watch(task_name, self._on_watched_task_ready) + logger.debug(f"Worker '{self}': watching for worker '{worker_name}'") + await self._registry.watch(worker_name, self._on_watched_worker_ready) async def request_job( self, - task_name: str, + worker_name: str, *, name: str | None = None, payload: dict | None = None, timeout: float | None = None, ) -> str: - """Send a job request to a single task (fire-and-forget). + """Send a job request to a single worker (fire-and-forget). - Waits for the task to be ready before sending the request. + Waits for the worker to be ready before sending the request. Does not wait for the job to complete; use callbacks (``on_job_response``, ``on_job_completed``) or ``job()`` for that. Args: - task_name: Name of the task to send the job to. + worker_name: Name of the worker to send the job to. name: Optional job name for routing to a named ``@job`` handler on the worker. payload: Optional structured data describing the work. @@ -638,7 +640,7 @@ class BaseTask(BaseObject, BusSubscriber): The generated job_id. """ group = await self.create_job_group_and_request_job( - [task_name], + [worker_name], name=name, payload=payload, timeout=timeout, @@ -648,15 +650,15 @@ class BaseTask(BaseObject, BusSubscriber): def job( self, - task_name: str, + worker_name: str, *, name: str | None = None, payload: dict | None = None, timeout: float | None = None, ) -> JobContext: - """Create a single-task job context manager. + """Create a single-worker job context manager. - Waits for the task to be ready, sends a job request, and + Waits for the worker to be ready, sends a job request, and waits for the response on exit. Supports ``async for`` inside the block to receive intermediate events (updates and streaming data) from the worker while waiting. @@ -665,7 +667,7 @@ class BaseTask(BaseObject, BusSubscriber): On worker error or timeout, raises ``JobError``. Args: - task_name: Name of the task to send the job to. + worker_name: Name of the worker to send the job to. name: Optional job name for routing to a named ``@job`` handler on the worker. payload: Optional structured data describing the work. @@ -685,7 +687,7 @@ class BaseTask(BaseObject, BusSubscriber): """ return JobContext( self, - task_name, + worker_name, name=name, payload=payload, timeout=timeout, @@ -693,21 +695,21 @@ class BaseTask(BaseObject, BusSubscriber): async def request_job_group( self, - *task_names: str, + *worker_names: str, name: str | None = None, payload: dict | None = None, timeout: float | None = None, cancel_on_error: bool = True, ) -> str: - """Send a job request to multiple tasks (fire-and-forget). + """Send a job request to multiple workers (fire-and-forget). - Waits for all tasks to be ready before sending requests. + Waits for all workers to be ready before sending requests. Does not wait for the job group to complete; use callbacks (``on_job_response``, ``on_job_completed``) or ``job_group()`` for that. Args: - *task_names: Names of the tasks to send the job to. + *worker_names: Names of the workers to send the job to. name: Optional job name for routing to named ``@job`` handlers on the workers. payload: Optional structured data describing the work. @@ -717,14 +719,16 @@ class BaseTask(BaseObject, BusSubscriber): worker responds with an error status. Defaults to True. Returns: - The generated job_id shared by all tasks in the group. + The generated job_id shared by all workers in the group. """ - for task_name in task_names: - if not isinstance(task_name, str): - raise TypeError(f"{self} Expected task name as str, got {type(task_name).__name__}") + for worker_name in worker_names: + if not isinstance(worker_name, str): + raise TypeError( + f"{self} Expected worker name as str, got {type(worker_name).__name__}" + ) group = await self.create_job_group_and_request_job( - list(task_names), + list(worker_names), name=name, payload=payload, timeout=timeout, @@ -734,7 +738,7 @@ class BaseTask(BaseObject, BusSubscriber): def job_group( self, - *task_names: str, + *worker_names: str, name: str | None = None, payload: dict | None = None, timeout: float | None = None, @@ -742,7 +746,7 @@ class BaseTask(BaseObject, BusSubscriber): ) -> JobGroupContext: """Create a job group context manager. - Waits for tasks to be ready, sends job requests, and waits + Waits for workers to be ready, sends job requests, and waits for all responses on exit. Supports ``async for`` inside the block to receive intermediate events (updates and streaming data) from workers while waiting. @@ -752,7 +756,7 @@ class BaseTask(BaseObject, BusSubscriber): raises ``JobGroupError``. Args: - *task_names: Names of the tasks to send the job to. + *worker_names: Names of the workers to send the job to. name: Optional job name for routing to named ``@job`` handlers on the workers. payload: Optional structured data describing the work. @@ -768,18 +772,20 @@ class BaseTask(BaseObject, BusSubscriber): async with self.job_group("w1", "w2", payload=data) as tg: async for event in tg: if event.type == JobGroupEvent.UPDATE: - print(f"{event.task_name}: {event.data}") + print(f"{event.worker_name}: {event.data}") for name, result in tg.responses.items(): print(name, result) """ - for task_name in task_names: - if not isinstance(task_name, str): - raise TypeError(f"{self} Expected task name as str, got {type(task_name).__name__}") + for worker_name in worker_names: + if not isinstance(worker_name, str): + raise TypeError( + f"{self} Expected worker name as str, got {type(worker_name).__name__}" + ) return JobGroupContext( self, - task_names, + worker_names, name=name, payload=payload, timeout=timeout, @@ -797,43 +803,43 @@ class BaseTask(BaseObject, BusSubscriber): if group: if group.timeout_task: await self.cancel_task(group.timeout_task) - for task_name in group.task_names: + for worker_name in group.worker_names: await self.send_bus_message( BusJobCancelMessage( - source=self.name, target=task_name, job_id=job_id, reason=reason + source=self.name, target=worker_name, job_id=job_id, reason=reason ) ) group.fail(reason) - async def request_job_update(self, job_id: str, task_name: str) -> None: + async def request_job_update(self, job_id: str, worker_name: str) -> None: """Request a progress update from a worker. Args: job_id: The job identifier. - task_name: The name of the worker to request an update from. + worker_name: The name of the worker to request an update from. """ await self.send_bus_message( - BusJobUpdateRequestMessage(source=self.name, target=task_name, job_id=job_id) + BusJobUpdateRequestMessage(source=self.name, target=worker_name, job_id=job_id) ) async def create_job_group_and_request_job( self, - task_names: list[str], + worker_names: list[str], *, name: str | None = None, payload: dict | None = None, timeout: float | None = None, cancel_on_error: bool = True, ) -> JobGroup: - """Wait for tasks to be ready, create a job group, and send requests. + """Wait for workers to be ready, create a job group, and send requests. - Waits for all tasks to be registered as ready, then creates - the group and sends a job request to each task. Does not wait + Waits for all workers to be registered as ready, then creates + the group and sends a job request to each worker. Does not wait for the group to complete; call ``group.wait()`` or use ``job_group()`` for that. Args: - task_names: Names of the tasks to send the job to. + worker_names: Names of the workers to send the job to. name: Optional job name for routing to named handlers. payload: Optional structured data describing the work. timeout: Optional timeout in seconds. Covers both the @@ -845,18 +851,20 @@ class BaseTask(BaseObject, BusSubscriber): The created ``JobGroup``. Raises: - JobGroupError: If tasks are not ready within the timeout. + JobGroupError: If workers are not ready within the timeout. """ - all_ready = await self._wait_tasks_ready(task_names) + all_ready = await self._wait_workers_ready(worker_names) try: await asyncio.wait_for(all_ready, timeout=timeout) except TimeoutError: - raise JobGroupError("tasks not ready within timeout") + raise JobGroupError("workers not ready within timeout") - group = self._create_job_group(task_names, timeout=timeout, cancel_on_error=cancel_on_error) + group = self._create_job_group( + worker_names, timeout=timeout, cancel_on_error=cancel_on_error + ) - for task_name in task_names: - await self._send_job_request(task_name, group.job_id, job_name=name, payload=payload) + for worker_name in worker_names: + await self._send_job_request(worker_name, group.job_id, job_name=name, payload=payload) return group @@ -884,7 +892,7 @@ class BaseTask(BaseObject, BusSubscriber): """ request = self._active_jobs.get(job_id) if request is None: - raise RuntimeError(f"Task '{self}': no active job '{job_id}' to respond to") + raise RuntimeError(f"Worker '{self}': no active job '{job_id}' to respond to") msg_class = BusJobResponseUrgentMessage if urgent else BusJobResponseMessage await self.send_bus_message( msg_class( @@ -913,7 +921,7 @@ class BaseTask(BaseObject, BusSubscriber): """ request = self._active_jobs.get(job_id) if request is None: - raise RuntimeError(f"Task '{self}': no active job '{job_id}' to update") + raise RuntimeError(f"Worker '{self}': no active job '{job_id}' to update") msg_class = BusJobUpdateUrgentMessage if urgent else BusJobUpdateMessage await self.send_bus_message( msg_class( @@ -936,7 +944,7 @@ class BaseTask(BaseObject, BusSubscriber): """ request = self._active_jobs.get(job_id) if request is None: - raise RuntimeError(f"Task '{self}': no active job '{job_id}' to stream") + raise RuntimeError(f"Worker '{self}': no active job '{job_id}' to stream") await self.send_bus_message( BusJobStreamStartMessage( source=self.name, @@ -958,7 +966,7 @@ class BaseTask(BaseObject, BusSubscriber): """ request = self._active_jobs.get(job_id) if request is None: - raise RuntimeError(f"Task '{self}': no active job '{job_id}' to stream") + raise RuntimeError(f"Worker '{self}': no active job '{job_id}' to stream") await self.send_bus_message( BusJobStreamDataMessage( source=self.name, @@ -969,7 +977,7 @@ class BaseTask(BaseObject, BusSubscriber): ) async def send_job_stream_end(self, job_id: str, data: dict | None = None) -> None: - """End the current stream and mark this task's job as complete. + """End the current stream and mark this worker's job as complete. Args: job_id: The identifier of the job being streamed. @@ -980,7 +988,7 @@ class BaseTask(BaseObject, BusSubscriber): """ request = self._active_jobs.get(job_id) if request is None: - raise RuntimeError(f"Task '{self}': no active job '{job_id}' to stream") + raise RuntimeError(f"Worker '{self}': no active job '{job_id}' to stream") await self.send_bus_message( BusJobStreamEndMessage( source=self.name, @@ -991,18 +999,18 @@ class BaseTask(BaseObject, BusSubscriber): ) async def _register_ready(self) -> None: - """Register this task as ready in the shared registry. + """Register this worker as ready in the shared registry. The registry notifies watchers (parent for children, runner - for root tasks). + for root workers). """ if self._registry: # Send the bus message before registering. Registration # fires watchers synchronously, which may send additional - # messages (e.g. ActivateTask). Sending the ready message + # messages (e.g. ActivateWorker). Sending the ready message # first preserves correct chronological order for observers. await self.send_bus_message( - BusTaskReadyMessage( + BusWorkerReadyMessage( source=self.name, runner=self._registry.runner_name, parent=self._parent, @@ -1012,115 +1020,115 @@ class BaseTask(BaseObject, BusSubscriber): ) ) await self._registry.register( - TaskReadyData( - task_name=self.name, + WorkerReadyData( + worker_name=self.name, runner=self._registry.runner_name, ) ) async def _maybe_activate(self) -> None: - """Activate the task, call on_activated, and fire event handlers.""" + """Activate the worker, call on_activated, and fire event handlers.""" if self._started_at is not None and self._pending_activation: - logger.debug(f"Task '{self}': activated") + logger.debug(f"Worker '{self}': activated") self._active = True self._pending_activation = False await self.on_activated(self._activation_args) await self._call_event_handler("on_activated", self._activation_args) - async def _watch_decorated_tasks(self) -> None: - """Register watches for all ``@task_ready`` decorated handlers.""" - for task_name in self._task_ready_handlers: - await self.watch_task(task_name) + async def _watch_decorated_workers(self) -> None: + """Register watches for all ``@worker_ready`` decorated handlers.""" + for worker_name in self._worker_ready_handlers: + await self.watch_worker(worker_name) - async def _on_watched_task_ready(self, data: TaskReadyData) -> None: - """Called when a watched task is ready. + async def _on_watched_worker_ready(self, data: WorkerReadyData) -> None: + """Called when a watched worker is ready. - Dispatches to the ``@task_ready`` handler if one exists for this - task, otherwise proxies to ``on_task_ready``. + Dispatches to the ``@worker_ready`` handler if one exists for this + worker, otherwise proxies to ``on_worker_ready``. """ - logger.debug(f"Task '{self}': task '{data.task_name}' ready") - handler = self._task_ready_handlers.get(data.task_name) + logger.debug(f"Worker '{self}': worker '{data.worker_name}' ready") + handler = self._worker_ready_handlers.get(data.worker_name) if handler: await handler(data) - await self.on_task_ready(data) - await self._call_event_handler("on_task_ready", data) + await self.on_worker_ready(data) + await self._call_event_handler("on_worker_ready", data) - async def _handle_task_error( - self, message: BusTaskErrorMessage | BusTaskLocalErrorMessage + async def _handle_worker_error( + self, message: BusWorkerErrorMessage | BusWorkerLocalErrorMessage ) -> None: - """Handle an error reported by a child or remote task.""" + """Handle an error reported by a child or remote worker.""" child_names = {child.name for child in self._children} if message.source in child_names: - error_info = TaskErrorData(task_name=message.source, error=message.error) - await self.on_task_failed(error_info) - await self._call_event_handler("on_task_failed", error_info) + error_info = WorkerErrorData(worker_name=message.source, error=message.error) + await self.on_worker_failed(error_info) + await self._call_event_handler("on_worker_failed", error_info) - async def _handle_task_activate(self, message: BusActivateTaskMessage) -> None: + async def _handle_worker_activate(self, message: BusActivateWorkerMessage) -> None: """Handle an activation message. - Stores the activation arguments and marks the task as pending + Stores the activation arguments and marks the worker as pending activation, then delegates to ``_maybe_activate()``. Args: - message: The ``BusActivateTaskMessage`` requesting activation. + message: The ``BusActivateWorkerMessage`` requesting activation. """ self._activation_args = message.args self._pending_activation = True await self._maybe_activate() - async def _handle_task_deactivate(self, message: BusDeactivateTaskMessage) -> None: - """Deactivate this task. + async def _handle_worker_deactivate(self, message: BusDeactivateWorkerMessage) -> None: + """Deactivate this worker. Args: - message: The ``BusDeactivateTaskMessage`` requesting deactivation. + message: The ``BusDeactivateWorkerMessage`` requesting deactivation. """ - logger.debug(f"Task '{self}': deactivated") + logger.debug(f"Worker '{self}': deactivated") self._active = False self._activation_args = None await self.on_deactivated() await self._call_event_handler("on_deactivated") - async def _handle_task_end(self, message: BusEndTaskMessage) -> None: - """Propagate end to children, wait for them, then stop this task. + async def _handle_worker_end(self, message: BusEndWorkerMessage) -> None: + """Propagate end to children, wait for them, then stop this worker. - Subclasses with their own runtime (e.g. `PipelineTask`) call + Subclasses with their own runtime (e.g. `PipelineWorker`) call :meth:`_propagate_end_to_children` directly and drive their own shutdown so ``_finished_event`` fires at the right moment. Args: - message: The ``BusEndTaskMessage`` requesting a graceful end. + message: The ``BusEndWorkerMessage`` requesting a graceful end. """ - logger.debug(f"Task '{self}': received end") + logger.debug(f"Worker '{self}': received end") await self._propagate_end_to_children(message) await self.stop() - async def _handle_task_cancel(self, message: BusCancelTaskMessage) -> None: - """Propagate cancel to children, then stop this task. + async def _handle_worker_cancel(self, message: BusCancelWorkerMessage) -> None: + """Propagate cancel to children, then stop this worker. - Subclasses with their own runtime (e.g. `PipelineTask`) call + Subclasses with their own runtime (e.g. `PipelineWorker`) call :meth:`_propagate_cancel_to_children` directly and drive their own shutdown so ``_finished_event`` fires at the right moment. Args: - message: The ``BusCancelTaskMessage`` requesting cancellation. + message: The ``BusCancelWorkerMessage`` requesting cancellation. """ - logger.debug(f"Task '{self}': received cancel") + logger.debug(f"Worker '{self}': received cancel") await self._propagate_cancel_to_children(message) await self.stop() - async def _propagate_end_to_children(self, message: BusEndTaskMessage) -> None: - """Forward a ``BusEndTaskMessage`` to each child and wait for them.""" + async def _propagate_end_to_children(self, message: BusEndWorkerMessage) -> None: + """Forward a ``BusEndWorkerMessage`` to each child and wait for them.""" for child in self._children: await self.send_bus_message( - BusEndTaskMessage(source=self.name, target=child.name, reason=message.reason) + BusEndWorkerMessage(source=self.name, target=child.name, reason=message.reason) ) await asyncio.gather(*(child.wait() for child in self._children)) - async def _propagate_cancel_to_children(self, message: BusCancelTaskMessage) -> None: - """Forward a ``BusCancelTaskMessage`` to each child.""" + async def _propagate_cancel_to_children(self, message: BusCancelWorkerMessage) -> None: + """Forward a ``BusCancelWorkerMessage`` to each child.""" for child in self._children: await self.send_bus_message( - BusCancelTaskMessage(source=self.name, target=child.name, reason=message.reason) + BusCancelWorkerMessage(source=self.name, target=child.name, reason=message.reason) ) async def _handle_job_request(self, message: BusJobRequestMessage) -> None: @@ -1128,7 +1136,7 @@ class BaseTask(BaseObject, BusSubscriber): Dispatches to @job handlers if any match, otherwise falls back to on_job_request. The handler always runs in its own asyncio - task so the bus message loop is never blocked. When the matched + worker so the bus message loop is never blocked. When the matched handler is marked ``sequential=True``, requests with the same job name are queued and run one at a time in FIFO order. """ @@ -1208,7 +1216,7 @@ class BaseTask(BaseObject, BusSubscriber): async def _handle_job_cancel(self, message: BusJobCancelMessage) -> None: """Handle a job cancellation. - Cancels the running handler task (if any), calls the + Cancels the running handler worker (if any), calls the ``on_job_cancelled`` hook for cleanup, then automatically sends a cancelled response back to the requester. The requester receives ``on_job_response`` with @@ -1251,13 +1259,15 @@ class BaseTask(BaseObject, BusSubscriber): def _create_job_group( self, - task_names: list[str], + worker_names: list[str], *, timeout: float | None = None, cancel_on_error: bool = True, ) -> JobGroup: job_id = str(uuid.uuid4()) - group = JobGroup(job_id=job_id, task_names=set(task_names), cancel_on_error=cancel_on_error) + group = JobGroup( + job_id=job_id, worker_names=set(worker_names), cancel_on_error=cancel_on_error + ) self._job_groups[job_id] = group if timeout is not None: @@ -1267,8 +1277,8 @@ class BaseTask(BaseObject, BusSubscriber): return group - async def _wait_tasks_ready(self, task_names: list[str]) -> asyncio.Future: - """Return a future that resolves when all named tasks are ready. + async def _wait_workers_ready(self, worker_names: list[str]) -> asyncio.Future: + """Return a future that resolves when all named workers are ready. Callers can race the returned future against a timeout or group done signal. @@ -1277,10 +1287,10 @@ class BaseTask(BaseObject, BusSubscriber): RuntimeError: If the registry is not available. """ if not self._registry: - raise RuntimeError(f"Task '{self}': registry not available") + raise RuntimeError(f"Worker '{self}': registry not available") ready_events: dict[str, asyncio.Event] = {} - for name in task_names: + for name in worker_names: event = asyncio.Event() ready_events[name] = event @@ -1293,7 +1303,7 @@ class BaseTask(BaseObject, BusSubscriber): async def _send_job_request( self, - task_name: str, + worker_name: str, job_id: str, job_name: str | None = None, payload: dict | None = None, @@ -1301,7 +1311,7 @@ class BaseTask(BaseObject, BusSubscriber): await self.send_bus_message( BusJobRequestMessage( source=self.name, - target=task_name, + target=worker_name, job_id=job_id, job_name=job_name, payload=payload, @@ -1327,7 +1337,7 @@ class BaseTask(BaseObject, BusSubscriber): group = self._job_groups.get(job_id) if group: group.responses[source] = response or {} - if group.responses.keys() >= group.task_names: + if group.responses.keys() >= group.worker_names: if group.timeout_task: await self.cancel_task(group.timeout_task) del self._job_groups[job_id] diff --git a/src/pipecat/pipeline/job_context.py b/src/pipecat/pipeline/job_context.py index 222896c66..2ff47baf7 100644 --- a/src/pipecat/pipeline/job_context.py +++ b/src/pipecat/pipeline/job_context.py @@ -4,7 +4,7 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""Task group types for structured concurrent task execution.""" +"""Worker group types for structured concurrent worker execution.""" from __future__ import annotations @@ -14,20 +14,20 @@ from enum import StrEnum from typing import TYPE_CHECKING, ClassVar if TYPE_CHECKING: - from pipecat.pipeline.base_task import BaseTask + from pipecat.pipeline.base_worker import BaseWorker class JobStatus(StrEnum): - """Status of a completed task. + """Status of a completed worker. Inherits from ``str`` so values compare naturally with plain strings and serialize without extra handling. Attributes: - COMPLETED: The task finished successfully. - CANCELLED: The task was cancelled by the requester. - FAILED: The task failed due to a logical or business error. - ERROR: The task encountered an unexpected runtime error. + COMPLETED: The worker finished successfully. + CANCELLED: The worker was cancelled by the requester. + FAILED: The worker failed due to a logical or business error. + ERROR: The worker encountered an unexpected runtime error. """ COMPLETED = "completed" @@ -37,13 +37,13 @@ class JobStatus(StrEnum): class JobError(Exception): - """Raised when a task is cancelled due to a worker error or timeout.""" + """Raised when a worker is cancelled due to a worker error or timeout.""" pass class JobGroupError(Exception): - """Raised when a task group is cancelled due to a worker error or timeout.""" + """Raised when a worker group is cancelled due to a worker error or timeout.""" pass @@ -85,7 +85,7 @@ class JobGroupEvent: Parameters: type: The event type. - task_name: The name of the worker that sent the event. + worker_name: The name of the worker that sent the event. data: Optional event payload. """ @@ -95,7 +95,7 @@ class JobGroupEvent: STREAM_END: ClassVar[str] = "stream_end" type: str - task_name: str + worker_name: str data: dict | None = None @@ -105,16 +105,16 @@ class JobGroup: Parameters: job_id: Shared identifier for all workers in this group. - task_names: Names of the workers in the group. + worker_names: Names of the workers in the group. responses: Collected responses keyed by worker name. - timeout_task: Optional asyncio task that cancels the group on timeout. + timeout_task: Optional asyncio worker that cancels the group on timeout. cancel_on_error: Whether to cancel the group if a worker errors. event_queue: Optional queue for streaming events to a ``JobGroupContext`` async iterator. """ job_id: str - task_names: set[str] + worker_names: set[str] responses: dict[str, dict] = field(default_factory=dict) timeout_task: asyncio.Task | None = None cancel_on_error: bool = True @@ -171,7 +171,7 @@ class JobGroupContext: async with self.job_group("w1", "w2", payload=data) as tg: async for event in tg: - print(f"{event.task_name} [{event.type}]: {event.data}") + print(f"{event.worker_name} [{event.type}]: {event.data}") for name, result in tg.responses.items(): print(name, result) @@ -179,8 +179,8 @@ class JobGroupContext: def __init__( self, - task: BaseTask, - task_names: tuple[str, ...], + worker: BaseWorker, + worker_names: tuple[str, ...], *, name: str | None = None, payload: dict | None = None, @@ -190,8 +190,8 @@ class JobGroupContext: """Initialize the JobGroupContext. Args: - task: The parent `BaseTask` that owns this job group. - task_names: Names of the workers to send the job to. + worker: The parent `BaseWorker` that owns this job group. + worker_names: Names of the workers to send the job to. name: Optional job name for routing to named ``@job`` handlers. payload: Optional structured data describing the work. timeout: Optional timeout in seconds covering both the @@ -199,8 +199,8 @@ class JobGroupContext: cancel_on_error: Whether to cancel the group if a worker errors. Defaults to True. """ - self._task = task - self._task_names = task_names + self._worker = worker + self._worker_names = worker_names self._name = name self._payload = payload self._timeout = timeout @@ -233,8 +233,8 @@ class JobGroupContext: return event async def __aenter__(self) -> JobGroupContext: - self._group = await self._task.create_job_group_and_request_job( - list(self._task_names), + self._group = await self._worker.create_job_group_and_request_job( + list(self._worker_names), name=self._name, payload=self._payload, timeout=self._timeout, @@ -245,12 +245,12 @@ class JobGroupContext: async def __aexit__(self, exc_type, exc_val, exc_tb) -> bool: if exc_type is not None: - if self._group and self._group.job_id in self._task.job_groups: + if self._group and self._group.job_id in self._worker.job_groups: # Shield the cleanup so it completes even if the - # surrounding task is being cancelled (e.g. tool + # surrounding worker is being cancelled (e.g. tool # interruption). await asyncio.shield( - self._task.cancel_job_group( + self._worker.cancel_job_group( self._group.job_id, reason="context exited with error" ) ) @@ -283,8 +283,8 @@ class JobContext: def __init__( self, - task: BaseTask, - task_name: str, + worker: BaseWorker, + worker_name: str, *, name: str | None = None, payload: dict | None = None, @@ -293,15 +293,15 @@ class JobContext: """Initialize the JobContext. Args: - task: The parent `BaseTask` that owns this job. - task_name: Name of the worker to send the job to. + worker: The parent `BaseWorker` that owns this job. + worker_name: Name of the worker to send the job to. name: Optional job name for routing to a named ``@job`` handler. payload: Optional structured data describing the work. timeout: Optional timeout in seconds covering both the ready-wait and job execution. """ - self._task = task - self._task_name = task_name + self._worker = worker + self._worker_name = worker_name self._name = name self._payload = payload self._timeout = timeout @@ -319,7 +319,7 @@ class JobContext: """The worker's response payload.""" if not self._group: raise RuntimeError("Job has not been started") - return self._group.responses.get(self._task_name, {}) + return self._group.responses.get(self._worker_name, {}) def __aiter__(self): return self @@ -333,8 +333,8 @@ class JobContext: return JobEvent(type=event.type, data=event.data) async def __aenter__(self) -> JobContext: - self._group = await self._task.create_job_group_and_request_job( - [self._task_name], + self._group = await self._worker.create_job_group_and_request_job( + [self._worker_name], name=self._name, payload=self._payload, timeout=self._timeout, @@ -345,12 +345,12 @@ class JobContext: async def __aexit__(self, exc_type, exc_val, exc_tb) -> bool: if exc_type is not None: - if self._group and self._group.job_id in self._task.job_groups: + if self._group and self._group.job_id in self._worker.job_groups: # Shield the cleanup so it completes even if the - # surrounding task is being cancelled (e.g. tool + # surrounding worker is being cancelled (e.g. tool # interruption). await asyncio.shield( - self._task.cancel_job_group( + self._worker.cancel_job_group( self._group.job_id, reason="context exited with error" ) ) diff --git a/src/pipecat/pipeline/job_decorator.py b/src/pipecat/pipeline/job_decorator.py index e91e8e7ca..53b234c10 100644 --- a/src/pipecat/pipeline/job_decorator.py +++ b/src/pipecat/pipeline/job_decorator.py @@ -4,15 +4,15 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""Decorator for marking task methods as job handlers.""" +"""Decorator for marking worker methods as job handlers.""" from collections.abc import Callable def job(*, name: str, sequential: bool = False): - """Mark a task method as a job handler. + """Mark a worker method as a job handler. - Decorated methods are automatically collected by ``BaseTask`` at + Decorated methods are automatically collected by ``BaseWorker`` at initialization and dispatched when matching job requests arrive. Each request runs in its own asyncio task so the bus message loop is never blocked. diff --git a/src/pipecat/pipeline/parallel_pipeline.py b/src/pipecat/pipeline/parallel_pipeline.py index d92fdada9..671aa131b 100644 --- a/src/pipecat/pipeline/parallel_pipeline.py +++ b/src/pipecat/pipeline/parallel_pipeline.py @@ -151,7 +151,7 @@ class ParallelPipeline(BasePipeline): # processors (e.g. output transport) begin shutting down while # other branches still have frames to flush, causing lost output. # - # - CancelFrame: PipelineTask waits for CancelFrame to reach the + # - CancelFrame: PipelineWorker waits for CancelFrame to reach the # pipeline sink. If it escapes from a fast branch while slower # branches are still running, the task considers cancellation # complete prematurely. diff --git a/src/pipecat/pipeline/runner.py b/src/pipecat/pipeline/runner.py index c667d8d94..257c1996c 100644 --- a/src/pipecat/pipeline/runner.py +++ b/src/pipecat/pipeline/runner.py @@ -4,37 +4,37 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""Pipeline runner for managing pipeline task execution and orchestration. +"""Pipeline runner for managing pipeline worker execution and orchestration. This module provides the :class:`PipelineRunner` class. It runs -:class:`~pipecat.pipeline.task.PipelineTask` instances to completion and -also acts as the host for spawned :class:`~pipecat.pipeline.base_task.BaseTask` -instances — owning the shared :class:`~pipecat.bus.TaskBus`, -the task registry, and the task manager that backs the entire session. +:class:`~pipecat.pipeline.worker.PipelineWorker` instances to completion and +also acts as the host for spawned :class:`~pipecat.pipeline.base_worker.BaseWorker` +instances — owning the shared :class:`~pipecat.bus.WorkerBus`, +the worker registry, and the worker manager that backs the entire session. For a typical single-pipeline bot, use :meth:`PipelineRunner.run` with the -task: +worker: .. code-block:: python runner = PipelineRunner() - await runner.run(task) + await runner.run(worker) -``run()`` returns when ``task`` finishes. +``run()`` returns when ``worker`` finishes. -For multi-task setups, spawn the additional tasks alongside the main one: +For multi-worker setups, add the additional workers alongside the main one: .. code-block:: python runner = PipelineRunner() - await runner.spawn(CodeWorker("code_worker", ...)) - await runner.run(task) + await runner.add_worker(CodeWorker("code_worker", ...)) + await runner.run(worker) -Optionally, ``spawn`` every task (including the main pipeline) and call +Optionally, ``add_worker`` every worker (including the main pipeline) and call ``run()`` with no argument. In that form ``run()`` blocks until :meth:`PipelineRunner.end` / :meth:`PipelineRunner.cancel` is called (or an incoming ``BusEndMessage`` / ``BusCancelMessage`` triggers the same path) — -spawned tasks finishing on their own does **not** unblock it. +added workers finishing on their own does **not** unblock it. """ import asyncio @@ -47,62 +47,62 @@ from loguru import logger from pipecat.bus import ( AsyncQueueBus, - BusAddTaskMessage, + BusAddWorkerMessage, BusCancelMessage, - BusCancelTaskMessage, + BusCancelWorkerMessage, BusEndMessage, - BusEndTaskMessage, + BusEndWorkerMessage, BusMessage, - BusTaskRegistryMessage, - TaskBus, + BusWorkerRegistryMessage, + WorkerBus, ) from pipecat.bus.subscriber import BusSubscriber -from pipecat.pipeline.base_task import BaseTask -from pipecat.pipeline.task import PipelineTask, PipelineTaskParams +from pipecat.pipeline.base_worker import BaseWorker from pipecat.pipeline.utils import run_setup_hook -from pipecat.registry import TaskRegistry -from pipecat.registry.types import TaskReadyData, TaskRegistryEntry +from pipecat.pipeline.worker import PipelineWorker, PipelineWorkerParams +from pipecat.registry import WorkerRegistry +from pipecat.registry.types import WorkerReadyData, WorkerRegistryEntry from pipecat.utils.asyncio.task_manager import TaskManager, TaskManagerParams from pipecat.utils.base_object import BaseObject @dataclass -class _TaskEntry: - """A task registered on the runner and its background asyncio task.""" +class _WorkerEntry: + """A worker registered on the runner and its background asyncio worker.""" - task: BaseTask + worker: BaseWorker runner_task: asyncio.Task | None = field(default=None, repr=False) class PipelineRunner(BaseObject, BusSubscriber): - """Manages pipeline task execution. + """Manages pipeline worker execution. - Provides a high-level interface for running pipeline tasks with + Provides a high-level interface for running pipeline workers with automatic signal handling (SIGINT/SIGTERM), optional garbage - collection, proper cleanup of resources, and a task bus + registry - for multi-task orchestration. + collection, proper cleanup of resources, and a worker bus + registry + for multi-worker orchestration. Two entry points: - - :meth:`run(task)` — block until the given pipeline task finishes. + - :meth:`run(worker)` — block until the given pipeline worker finishes. The most common case for a single-pipeline bot. - - :meth:`spawn(task)` — fire-and-forget; register a child task on - the runner's bus and start it in the background. Spawned tasks - run alongside the main task and are cancelled when the main task - finishes (or when :meth:`end` / :meth:`cancel` is called). + - :meth:`add_worker(worker)` — register a worker on the runner's bus and + start it in the background. Added workers run alongside the main + worker and are cancelled when the main worker finishes (or when + :meth:`end` / :meth:`cancel` is called). Event handlers available: - ``on_ready`` — fired after the runner has finished its - initialization and any spawned tasks have been started. - - ``on_error`` — fired when starting a spawned task fails. + initialization and any added workers have been started. + - ``on_error`` — fired when starting an added worker fails. """ def __init__( self, *, name: str | None = None, - bus: TaskBus | None = None, + bus: WorkerBus | None = None, handle_sigint: bool = True, handle_sigterm: bool = False, force_gc: bool = False, @@ -114,20 +114,20 @@ class PipelineRunner(BaseObject, BusSubscriber): name: Optional name for the runner instance. Defaults to a UUID-based name. Must be unique across runners in a distributed setup. - bus: Optional :class:`TaskBus`. Defaults to a new + bus: Optional :class:`WorkerBus`. Defaults to a new in-process :class:`AsyncQueueBus`. handle_sigint: Whether to automatically handle SIGINT signals. handle_sigterm: Whether to automatically handle SIGTERM signals. force_gc: Whether to force garbage collection after the main - task completes. + worker completes. loop: Event loop to use. If None, uses the current running loop. """ super().__init__(name=name or f"runner-{uuid.uuid4().hex[:8]}") - self._bus: TaskBus = bus or AsyncQueueBus() - self._registry = TaskRegistry(runner_name=self.name) + self._bus: WorkerBus = bus or AsyncQueueBus() + self._registry = WorkerRegistry(runner_name=self.name) - self._entries: dict[str, _TaskEntry] = {} + self._entries: dict[str, _WorkerEntry] = {} self._known_runners: set[str] = set() self._running: bool = False self._shutdown_event = asyncio.Event() @@ -142,75 +142,81 @@ class PipelineRunner(BaseObject, BusSubscriber): self._register_event_handler("on_error") @property - def bus(self) -> TaskBus: - """The bus this runner hosts; shared across spawned tasks.""" + def bus(self) -> WorkerBus: + """The bus this runner hosts; shared across launched workers.""" return self._bus @property - def registry(self) -> TaskRegistry: - """The task registry this runner owns.""" + def registry(self) -> WorkerRegistry: + """The worker registry this runner owns.""" return self._registry - async def spawn(self, task: BaseTask) -> None: - """Register a task with the runner and start it in the background. + async def add_worker(self, worker: BaseWorker) -> None: + """Add a worker to the runner. - Can be called before or after :meth:`run`. When called after - ``run()`` has started, the task is started immediately. Spawned - tasks run alongside the main task and are cancelled when the - main task finishes or when :meth:`end` / :meth:`cancel` is - called. + Adding a worker attaches it to the runner's bus and registry, and + starts it in the background. If the runner is not yet running + (``add_worker`` was called before :meth:`run`), the worker is + queued and started during run setup; if the runner is already + running, the worker starts immediately. + + Added workers run alongside the main worker and are cancelled + when the main worker finishes (or when :meth:`end` / + :meth:`cancel` is called). Args: - task: The task to spawn. + worker: The worker to add. """ - if task.name in self._entries: - logger.error(f"PipelineRunner '{self}': task '{task.name}' already exists, skipping") + if worker.name in self._entries: + logger.error( + f"PipelineRunner '{self}': worker '{worker.name}' already exists, skipping" + ) return - task.attach(registry=self._registry, bus=self._bus) - await self._registry.watch(task.name, self._on_local_task_ready) - entry = _TaskEntry(task=task) - self._entries[task.name] = entry - logger.debug(f"PipelineRunner '{self}': spawned task '{task.name}'") + worker.attach(registry=self._registry, bus=self._bus) + await self._registry.watch(worker.name, self._on_local_worker_ready) + entry = _WorkerEntry(worker=worker) + self._entries[worker.name] = entry + logger.debug(f"PipelineRunner '{self}': added worker '{worker.name}'") if self._running: - await self._start_task(entry) + await self._start_worker(entry) - async def run(self, task: PipelineTask | None = None) -> None: - """Run a pipeline task to completion (optionally alongside spawned tasks). + async def run(self, worker: PipelineWorker | None = None) -> None: + """Run a pipeline worker to completion (optionally alongside added workers). - If ``task`` is provided, blocks until that task finishes. Any - spawned tasks are started in the background and cancelled - when the main task finishes. + If ``worker`` is provided, blocks until that worker finishes. Any + added workers are started in the background and cancelled + when the main worker finishes. - If ``task`` is None, blocks until :meth:`end` or :meth:`cancel` + If ``worker`` is None, blocks until :meth:`end` or :meth:`cancel` is called (or until an incoming ``BusEndMessage`` / - ``BusCancelMessage`` triggers the same path). Spawned tasks + ``BusCancelMessage`` triggers the same path). Added workers finishing on their own does **not** unblock the runner — use this form for hosts that have no single "main" pipeline and want to stay up across many spawned sessions (e.g. a FastAPI server). If you want the runner to finish when a specific - pipeline finishes, pass that pipeline as ``task``. + pipeline finishes, pass that pipeline as ``worker``. Args: - task: The pipeline task to run, or None. + worker: The pipeline worker to run, or None. """ - logger.debug(f"PipelineRunner '{self}': started running {task}") + logger.debug(f"PipelineRunner '{self}': started running {worker}") self._shutdown_event.clear() - # Treat the main task as a spawned task: ``spawn`` attaches it - # to the bus and registry, and ``_setup_session`` then starts - # every entry (main and pre-spawned) through the same code path. - if task is not None: - await self.spawn(task) + # Treat the main worker as any other added worker: ``add_worker`` attaches + # it to the bus and registry, and ``_setup_session`` then starts every + # entry (main and pre-added) through the same code path. + if worker is not None: + await self.add_worker(worker) await self._setup_session() await self._call_event_handler("on_ready") - # Wait for the main task's background runner task to finish - # (or for an explicit shutdown when there's no main task). + # Wait for the main worker's background runner worker to finish + # (or for an explicit shutdown when there's no main worker). try: - if task is not None: - runner_task = self._entries[task.name].runner_task + if worker is not None: + runner_task = self._entries[worker.name].runner_task if runner_task is not None: await runner_task else: @@ -218,7 +224,7 @@ class PipelineRunner(BaseObject, BusSubscriber): except asyncio.CancelledError: pass - # Cancel any remaining spawned tasks and wait for them to finish. + # Cancel any remaining launched workers and wait for them to finish. await self._cancel_spawned_tasks() # Cleanup base object. @@ -235,21 +241,21 @@ class PipelineRunner(BaseObject, BusSubscriber): if self._force_gc: await self._gc_collect() - logger.debug(f"PipelineRunner '{self}': finished running {task}") + logger.debug(f"PipelineRunner '{self}': finished running {worker}") async def stop_when_done(self) -> None: - """Schedule all root pipeline tasks to stop when their current processing is complete.""" - logger.debug(f"PipelineRunner '{self}': scheduled to stop when all tasks are done") + """Schedule all root pipeline workers to stop when their current processing is complete.""" + logger.debug(f"PipelineRunner '{self}': scheduled to stop when all workers are done") await asyncio.gather( *[ - entry.task.stop_when_done() + entry.worker.stop_when_done() for entry in self._entries.values() - if isinstance(entry.task, PipelineTask) and entry.task.parent is None + if isinstance(entry.worker, PipelineWorker) and entry.worker.parent is None ] ) async def end(self, reason: str | None = None) -> None: - """Gracefully end all running tasks. + """Gracefully end all running workers. Idempotent; subsequent calls are ignored. @@ -261,13 +267,13 @@ class PipelineRunner(BaseObject, BusSubscriber): logger.debug(f"PipelineRunner '{self}': ending gracefully (reason={reason})") self._shutdown_event.set() for name, entry in self._entries.items(): - if entry.task.parent is None: + if entry.worker.parent is None: await self._bus.send( - BusEndTaskMessage(source=self.name, target=name, reason=reason) + BusEndWorkerMessage(source=self.name, target=name, reason=reason) ) async def cancel(self, reason: str | None = None) -> None: - """Immediately cancel all running tasks. + """Immediately cancel all running workers. Idempotent; subsequent calls are ignored. @@ -279,9 +285,9 @@ class PipelineRunner(BaseObject, BusSubscriber): logger.debug(f"PipelineRunner '{self}': cancelling (reason={reason})") self._shutdown_event.set() for name, entry in self._entries.items(): - if entry.task.parent is None: + if entry.worker.parent is None: await self._bus.send( - BusCancelTaskMessage(source=self.name, target=name, reason=reason) + BusCancelWorkerMessage(source=self.name, target=name, reason=reason) ) async def on_bus_message(self, message: BusMessage) -> None: @@ -292,13 +298,13 @@ class PipelineRunner(BaseObject, BusSubscriber): self.create_task(self.end(message.reason), "end") elif isinstance(message, BusCancelMessage): self.create_task(self.cancel(message.reason), "cancel") - elif isinstance(message, BusAddTaskMessage) and message.task: - await self.spawn(message.task) - elif isinstance(message, BusTaskRegistryMessage): - await self._handle_task_registry(message) + elif isinstance(message, BusAddWorkerMessage) and message.worker: + await self.add_worker(message.worker) + elif isinstance(message, BusWorkerRegistryMessage): + await self._handle_worker_registry(message) async def _setup_session(self) -> None: - """One-time per-run setup: task manager, bus, signal handlers, spawned tasks.""" + """One-time per-run setup: worker manager, bus, signal handlers, launched workers.""" if self._running: return task_manager = TaskManager() @@ -317,12 +323,12 @@ class PipelineRunner(BaseObject, BusSubscriber): await self._load_setup_files() for entry in self._entries.values(): - await self._start_task(entry) + await self._start_worker(entry) self._running = True async def _cancel_spawned_tasks(self) -> None: - """Wait for spawned runner tasks to finish (or cancel them).""" + """Wait for added workers' runner tasks to finish (or cancel them).""" remaining = [ e.runner_task for e in self._entries.values() @@ -331,10 +337,10 @@ class PipelineRunner(BaseObject, BusSubscriber): if not remaining: return for entry in self._entries.values(): - if entry.task.parent is None: + if entry.worker.parent is None: await self._bus.send( - BusCancelTaskMessage( - source=self.name, target=entry.task.name, reason="runner exiting" + BusCancelWorkerMessage( + source=self.name, target=entry.worker.name, reason="runner exiting" ) ) await asyncio.gather(*remaining, return_exceptions=True) @@ -342,73 +348,74 @@ class PipelineRunner(BaseObject, BusSubscriber): async def _load_setup_files(self) -> None: """Run ``setup_pipeline_runner`` from each file in ``PIPECAT_SETUP_FILES``. - A setup file may define ``setup_pipeline_runner(runner)`` to attach - spawned tasks, event handlers, or other runner-level wiring. + A setup file may define ``setup_pipeline_runner(runner)`` to add + workers, attach event handlers, or wire other runner-level + configuration. """ await run_setup_hook(target=self, function_name="setup_pipeline_runner") - async def _start_task(self, entry: _TaskEntry) -> None: - """Run a registered task as a background asyncio task.""" - task = entry.task - logger.debug(f"PipelineRunner '{self}': starting task '{task.name}'") + async def _start_worker(self, entry: _WorkerEntry) -> None: + """Run a registered worker as a background asyncio worker.""" + worker = entry.worker + logger.debug(f"PipelineRunner '{self}': starting worker '{worker.name}'") entry.runner_task = self.create_task( - self._run_task(task), - f"task_{task.name}", + self._run_worker(worker), + f"task_{worker.name}", ) - # Add the task to event loop right away without needing to `await`. + # Add the worker to event loop right away without needing to `await`. await asyncio.sleep(0) - async def _run_task(self, task: BaseTask) -> None: - """Drive a registered task to completion.""" + async def _run_worker(self, worker: BaseWorker) -> None: + """Drive a registered worker to completion.""" try: - params = PipelineTaskParams(loop=self._loop) - await task.run(params) + params = PipelineWorkerParams(loop=self._loop) + await worker.run(params) except asyncio.CancelledError: pass - async def _on_local_task_ready(self, data: TaskReadyData) -> None: - """Called when a local spawned task registers as ready.""" + async def _on_local_worker_ready(self, data: WorkerReadyData) -> None: + """Called when a local added worker registers as ready.""" if data.runner != self.name: return - entry = self._entries.get(data.task_name) - if not entry or entry.task.parent is not None: + entry = self._entries.get(data.worker_name) + if not entry or entry.worker.parent is not None: return await self._send_registry() async def _send_registry(self) -> None: - """Broadcast this runner's tasks to the bus.""" - tasks = [ - TaskRegistryEntry( - name=entry.task.name, - parent=entry.task.parent, - active=entry.task.active, - bridged=entry.task.bridged, - started_at=entry.task.started_at, + """Broadcast this runner's workers to the bus.""" + workers = [ + WorkerRegistryEntry( + name=entry.worker.name, + parent=entry.worker.parent, + active=entry.worker.active, + bridged=entry.worker.bridged, + started_at=entry.worker.started_at, ) for entry in self._entries.values() ] - if tasks: - names = [t.name for t in tasks] + if workers: + names = [w.name for w in workers] logger.debug(f"PipelineRunner '{self}': broadcasting registry: {names}") await self._bus.send( - BusTaskRegistryMessage( + BusWorkerRegistryMessage( source=self.name, runner=self.name, - tasks=tasks, + workers=workers, ) ) - async def _handle_task_registry(self, message: BusTaskRegistryMessage) -> None: + async def _handle_worker_registry(self, message: BusWorkerRegistryMessage) -> None: """Handle a registry message from a remote runner.""" - task_names = [t.name for t in message.tasks] + worker_names = [w.name for w in message.workers] logger.debug( f"PipelineRunner '{self}': received registry from '{message.runner}' " - f"with tasks: {task_names}" + f"with workers: {worker_names}" ) - for entry in message.tasks: + for entry in message.workers: await self._registry.register( - TaskReadyData(task_name=entry.name, runner=message.runner) + WorkerReadyData(worker_name=entry.name, runner=message.runner) ) if message.runner not in self._known_runners: self._known_runners.add(message.runner) diff --git a/src/pipecat/pipeline/task.py b/src/pipecat/pipeline/task.py index f8f4e993c..345956953 100644 --- a/src/pipecat/pipeline/task.py +++ b/src/pipecat/pipeline/task.py @@ -4,1097 +4,28 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""Pipeline task implementation for managing frame processing pipelines. +"""Deprecated module. -This module provides the main PipelineTask class that orchestrates pipeline -execution, frame routing, lifecycle management, and monitoring capabilities -including heartbeats, idle detection, and observer integration. +.. deprecated:: 1.3.0 + Import from :mod:`pipecat.pipeline.worker` instead. Constructing + :class:`PipelineTask` directly is also deprecated; use + :class:`PipelineWorker`. """ -import asyncio -import warnings -from collections.abc import AsyncIterable, Iterable -from dataclasses import dataclass -from typing import Any, TypeVar - -from loguru import logger -from pydantic import BaseModel, ConfigDict, Field - -from pipecat.bus import BusCancelTaskMessage, BusEndTaskMessage, TaskBus -from pipecat.bus.bridge_processor import _BusEdgeProcessor -from pipecat.clocks.base_clock import BaseClock -from pipecat.clocks.system_clock import SystemClock -from pipecat.frames.frames import ( - BotSpeakingFrame, - CancelFrame, - CancelTaskFrame, - EndFrame, - EndTaskFrame, - ErrorFrame, - Frame, - HeartbeatFrame, - InterruptionFrame, - InterruptionTaskFrame, - MetricsFrame, - StartFrame, - StopFrame, - StopTaskFrame, - UserSpeakingFrame, +from pipecat.pipeline.worker import ( + IdleFrameObserver, + PipelineParams, + PipelineTask, + PipelineTaskParams, + PipelineWorker, + PipelineWorkerParams, ) -from pipecat.metrics.metrics import ProcessingMetricsData, TTFBMetricsData -from pipecat.observers.base_observer import BaseObserver, FramePushed -from pipecat.observers.turn_tracking_observer import TurnTrackingObserver -from pipecat.observers.user_bot_latency_observer import UserBotLatencyObserver -from pipecat.pipeline.base_pipeline import BasePipeline -from pipecat.pipeline.base_task import BaseTask -from pipecat.pipeline.pipeline import Pipeline, PipelineSink, PipelineSource -from pipecat.pipeline.task_observer import TaskObserver -from pipecat.pipeline.utils import run_setup_hook -from pipecat.processors.frame_processor import FrameDirection, FrameProcessor, FrameProcessorSetup -from pipecat.processors.frameworks.rtvi import RTVIObserver, RTVIObserverParams, RTVIProcessor -from pipecat.utils.asyncio.task_manager import BaseTaskManager, TaskManager, TaskManagerParams -from pipecat.utils.tracing.setup import is_tracing_available -from pipecat.utils.tracing.tracing_context import TracingContext -from pipecat.utils.tracing.turn_trace_observer import TurnTraceObserver -HEARTBEAT_SECS = 1.0 -HEARTBEAT_MONITOR_SECS = 10.0 - -IDLE_TIMEOUT_SECS = 300 - -CANCEL_TIMEOUT_SECS = 20.0 - - -T = TypeVar("T") - - -@dataclass -class PipelineTaskParams: - """Configuration parameters for pipeline task execution. - - Parameters: - loop: The asyncio event loop to use for task execution. - """ - - loop: asyncio.AbstractEventLoop - - -class IdleFrameObserver(BaseObserver): - """Idle timeout observer. - - This observer waits for specific frames being generated in the pipeline. If - the frames are generated the given asyncio event is set. If the event is not - set it means the pipeline is probably idle. - - """ - - def __init__(self, *, idle_event: asyncio.Event, idle_timeout_frames: tuple[type[Frame], ...]): - """Initialize the observer. - - Args: - idle_event: The event to set if the idle timeout frames are being pushed. - idle_timeout_frames: A tuple with the frames that should set the event when received - """ - super().__init__() - self._idle_event = idle_event - self._idle_timeout_frames = idle_timeout_frames - self._processed_frames = set() - - async def on_push_frame(self, data: FramePushed): - """Callback executed when a frame is pushed in the pipeline. - - Args: - data: The frame push event data. - """ - # Skip already processed frames - if data.frame.id in self._processed_frames: - return - - self._processed_frames.add(data.frame.id) - - if isinstance(data.frame, StartFrame) or isinstance(data.frame, self._idle_timeout_frames): - self._idle_event.set() - - -class PipelineParams(BaseModel): - """Configuration parameters for pipeline execution. - - These parameters are usually passed to all frame processors through - StartFrame. For other generic pipeline task parameters use PipelineTask - constructor arguments instead. - - Parameters: - audio_in_sample_rate: Input audio sample rate in Hz. - audio_out_sample_rate: Output audio sample rate in Hz. - enable_heartbeats: Whether to enable heartbeat monitoring. - enable_metrics: Whether to enable metrics collection. - enable_usage_metrics: Whether to enable usage metrics. - heartbeats_period_secs: Period between heartbeats in seconds. - heartbeats_monitor_secs: Timeout (in seconds) before warning about - missed heartbeats. Defaults to 10 seconds. - report_only_initial_ttfb: Whether to report only initial time to first byte. - send_initial_empty_metrics: Whether to send initial empty metrics. - start_metadata: Additional metadata for pipeline start. - """ - - model_config = ConfigDict(arbitrary_types_allowed=True) - - audio_in_sample_rate: int = 16000 - audio_out_sample_rate: int = 24000 - enable_heartbeats: bool = False - enable_metrics: bool = False - enable_usage_metrics: bool = False - heartbeats_period_secs: float = HEARTBEAT_SECS - heartbeats_monitor_secs: float = HEARTBEAT_MONITOR_SECS - report_only_initial_ttfb: bool = False - send_initial_empty_metrics: bool = True - start_metadata: dict[str, Any] = Field(default_factory=dict) - - -class PipelineTask(BaseTask): - """Manages the execution of a pipeline, handling frame processing and task lifecycle. - - This class orchestrates pipeline execution with comprehensive monitoring, - event handling, and lifecycle management. It provides event handlers for - various pipeline states and frame types, idle detection, heartbeat monitoring, - and observer integration. - - Event handlers available: - - - on_frame_reached_upstream: Called when upstream frames reach the source - - on_frame_reached_downstream: Called when downstream frames reach the sink - - on_idle_timeout: Called when pipeline is idle beyond timeout threshold - - on_pipeline_started: Called when pipeline starts with StartFrame - - on_pipeline_finished: Called after the pipeline has reached any terminal state. - This includes: - - - StopFrame: pipeline was stopped (processors keep connections open) - - EndFrame: pipeline ended normally - - CancelFrame: pipeline was cancelled - - Use this event for cleanup, logging, or post-processing tasks. Users can inspect - the frame if they need to handle specific cases. - - - on_pipeline_error: Called when an error occurs with ErrorFrame - - Example:: - - @task.event_handler("on_frame_reached_upstream") - async def on_frame_reached_upstream(task, frame): - ... - - @task.event_handler("on_idle_timeout") - async def on_pipeline_idle_timeout(task): - ... - - @task.event_handler("on_pipeline_started") - async def on_pipeline_started(task, frame): - ... - - @task.event_handler("on_pipeline_finished") - async def on_pipeline_finished(task, frame): - ... - - @task.event_handler("on_pipeline_error") - async def on_pipeline_error(task, frame): - ... - """ - - def __init__( - self, - pipeline: BasePipeline, - *, - additional_span_attributes: dict | None = None, - app_resources: Any = None, - bridged: tuple[str, ...] | None = None, - cancel_on_idle_timeout: bool = True, - cancel_timeout_secs: float = CANCEL_TIMEOUT_SECS, - check_dangling_tasks: bool = True, - clock: BaseClock | None = None, - conversation_id: str | None = None, - enable_tracing: bool = False, - enable_turn_tracking: bool = True, - enable_rtvi: bool = True, - exclude_frames: tuple[type[Frame], ...] | None = None, - idle_timeout_frames: tuple[type[Frame], ...] = (BotSpeakingFrame, UserSpeakingFrame), - idle_timeout_secs: float | None = IDLE_TIMEOUT_SECS, - name: str | None = None, - observers: list[BaseObserver] | None = None, - params: PipelineParams | None = None, - rtvi_processor: RTVIProcessor | None = None, - rtvi_observer_params: RTVIObserverParams | None = None, - task_manager: BaseTaskManager | None = None, - tool_resources: Any = None, - ): - """Initialize the PipelineTask. - - Args: - pipeline: The pipeline to execute. - additional_span_attributes: Optional dictionary of attributes to propagate as - OpenTelemetry conversation span attributes. - app_resources: Optional application-defined bag of anything your - application code may want to share across this session (DB - handles, HTTP clients, etc.), passed by reference. Pipecat - passes it through untouched and exposes it on the task itself - as ``task.app_resources`` and passes it to tool handlers as - ``FunctionCallParams.app_resources``. The framework never - copies or clears this object; the caller retains their handle - and can read any mutations after the task finishes. - bridged: Bridge configuration. ``None`` means the pipeline - is not bridged. An empty tuple ``()`` wraps the pipeline - with bus edge processors that accept frames from all - bridges. A tuple of names like ``("voice",)`` accepts - only frames from those bridges. The bus comes from - :meth:`attach` (called by the runner). - cancel_on_idle_timeout: Whether the pipeline task should be cancelled if - the idle timeout is reached. - cancel_timeout_secs: Timeout (in seconds) to wait for cancellation to happen - cleanly. - check_dangling_tasks: Whether to check for processors' tasks finishing properly. - clock: Clock implementation for timing operations. - conversation_id: Optional custom ID for the conversation. - enable_rtvi: Whether to automatically add RTVI support to the pipeline. - enable_tracing: Whether to enable tracing. - enable_turn_tracking: Whether to enable turn tracking. - exclude_frames: When ``bridged`` is set, extra frame types - that should not cross the bus (lifecycle frames are - always excluded). - idle_timeout_frames: A tuple with the frames that should trigger an idle - timeout if not received within `idle_timeout_seconds`. - idle_timeout_secs: Timeout (in seconds) to consider pipeline idle or - None. If a pipeline is idle the pipeline task will be cancelled - automatically. - name: Optional task name (used for task-style addressing on the bus). - observers: List of observers for monitoring pipeline execution. - params: Configuration parameters for the pipeline. - rtvi_observer_params: The RTVI observer parameter to use if RTVI is enabled. - rtvi_processor: The RTVI processor to add if RTVI is enabled. - task_manager: Optional task manager for handling asyncio tasks. - tool_resources: Deprecated alias for ``app_resources``. - - .. deprecated:: 1.2.0 - Use ``app_resources`` instead. ``tool_resources`` will be - removed in a future version. - """ - super().__init__(name=name) - self._bridged = bridged - if tool_resources is not None: - with warnings.catch_warnings(): - warnings.simplefilter("always") - warnings.warn( - "`PipelineTask(tool_resources=...)` is deprecated since 1.2.0, " - "use `app_resources` instead.", - DeprecationWarning, - stacklevel=2, - ) - if app_resources is None: - app_resources = tool_resources - self._params = params or PipelineParams() - self._additional_span_attributes = additional_span_attributes or {} - self._cancel_on_idle_timeout = cancel_on_idle_timeout - self._cancel_timeout_secs = cancel_timeout_secs - self._check_dangling_tasks = check_dangling_tasks - self._clock = clock or SystemClock() - self._conversation_id = conversation_id - self._enable_tracing = enable_tracing and is_tracing_available() - self._enable_turn_tracking = enable_turn_tracking - self._idle_timeout_secs = idle_timeout_secs - self._app_resources = app_resources - observers = observers or [] - self._turn_tracking_observer: TurnTrackingObserver | None = None - self._user_bot_latency_observer: UserBotLatencyObserver | None = None - self._turn_trace_observer: TurnTraceObserver | None = None - self._tracing_context: TracingContext | None = None - if self._enable_turn_tracking: - self._turn_tracking_observer = TurnTrackingObserver() - observers.append(self._turn_tracking_observer) - if self._enable_tracing and self._turn_tracking_observer: - # Create pipeline-scoped tracing context - self._tracing_context = TracingContext() - # Create latency observer for tracing - self._user_bot_latency_observer = UserBotLatencyObserver() - observers.append(self._user_bot_latency_observer) - # Create turn trace observer with latency tracking - self._turn_trace_observer = TurnTraceObserver( - self._turn_tracking_observer, - latency_tracker=self._user_bot_latency_observer, - conversation_id=self._conversation_id, - additional_span_attributes=self._additional_span_attributes, - tracing_context=self._tracing_context, - ) - observers.append(self._turn_trace_observer) - - self._finished = False - self._cancelled = False - - # This task maneger will handle all the asyncio tasks created by this - # PipelineTask and its frame processors. - self._pipeline_task_manager = task_manager or TaskManager() - - # This queue is the queue used to push frames to the pipeline. - self._push_queue = asyncio.Queue() - self._process_push_task: asyncio.Task | None = None - - # This is the heartbeat queue. When a heartbeat frame is received in the - # down queue we add it to the heartbeat queue for processing. - self._heartbeat_queue = asyncio.Queue() - self._heartbeat_push_task: asyncio.Task | None = None - self._heartbeat_monitor_task: asyncio.Task | None = None - - # RTVI support - self._rtvi = None - prepend_rtvi = False - external_rtvi = self._find_processor(pipeline, RTVIProcessor) - external_observer_found = any(isinstance(o, RTVIObserver) for o in observers) - - if external_rtvi and not external_observer_found: - logger.error( - f"{self}: RTVIProcessor found in pipeline but no RTVIObserver in observers. " - "Make sure to add both." - ) - elif not external_rtvi and external_observer_found: - logger.error( - f"{self}: RTVIObserver found in observers but no RTVIProcessor in pipeline. " - "Make sure to add both." - ) - elif external_rtvi and external_observer_found: - logger.warning( - f"{self}: RTVIProcessor and RTVIObserver found, skipping default ones. " - "They are both added by default, no need to add them yourself." - ) - self._rtvi = external_rtvi - elif enable_rtvi: - self._rtvi = rtvi_processor or RTVIProcessor() - observers.append(self._rtvi.create_rtvi_observer(params=rtvi_observer_params)) - prepend_rtvi = True - - if self._rtvi: - # Automatically call RTVIProcessor.set_bot_ready() - @self.rtvi.event_handler("on_client_ready") - async def on_client_ready(rtvi: RTVIProcessor): - await rtvi.set_bot_ready() - - # This is the idle event. When selected frames are pushed from any - # processor we consider the pipeline is not idle. We use an observer - # which will be listening any part of the pipeline. - self._idle_event = asyncio.Event() - self._idle_monitor_task: asyncio.Task | None = None - if self._idle_timeout_secs: - idle_frame_observer = IdleFrameObserver( - idle_event=self._idle_event, - idle_timeout_frames=idle_timeout_frames, - ) - observers.append(idle_frame_observer) - - # This event is used to indicate the StartFrame has been received at the - # end of the pipeline. - self._pipeline_start_event = asyncio.Event() - - # This event is used to indicate a finalize frame (e.g. EndFrame, - # StopFrame) has been received at the end of the pipeline. - self._pipeline_end_event = asyncio.Event() - - # When bridged, wrap the user pipeline with bus edge processors - # so frames tee onto the bus at the source/sink and incoming bus - # frames are injected back into the local pipeline. The edges - # read the task's bus lazily, so the bus only needs to be set - # (via ``attach()``) before ``run()`` is called. - if bridged is not None: - edge_source = _BusEdgeProcessor( - task=self, - direction=FrameDirection.UPSTREAM, - bridges=bridged, - exclude_frames=exclude_frames, - name=f"{self}::EdgeSource", - ) - edge_sink = _BusEdgeProcessor( - task=self, - direction=FrameDirection.DOWNSTREAM, - bridges=bridged, - exclude_frames=exclude_frames, - name=f"{self}::EdgeSink", - ) - pipeline = Pipeline([edge_source, pipeline, edge_sink]) - - # This is the final pipeline. It is composed of a source processor, - # followed by the user pipeline, and ending with a sink processor. The - # source allows us to receive and react to upstream frames, and the sink - # allows us to receive and react to downstream frames. - source = PipelineSource(self._source_push_frame, name=f"{self}::Source") - self._sink = PipelineSink(self._sink_push_frame, name=f"{self}::Sink") - # Only prepend the RTVIProcessor if we created it ourselves. When the - # user already placed it inside their pipeline we must not insert it - # again or it will appear twice in the frame chain. - processors = [self._rtvi, pipeline] if prepend_rtvi else [pipeline] - self._pipeline = Pipeline(processors, source=source, sink=self._sink) - - # The task observer acts as a proxy to the provided observers. This way, - # we only need to pass a single observer (using the StartFrame) which - # then just acts as a proxy. - self._observer = TaskObserver(observers=observers) - - # These events can be used to check which frames make it to the source - # or sink processors. Instead of calling the event handlers for every - # frame the user needs to specify which events they are interested - # in. This is mainly for efficiency reason because each event handler - # creates a task and most likely you only care about one or two frame - # types. - self._reached_upstream_types: set[type[Frame]] = set() - self._reached_downstream_types: set[type[Frame]] = set() - self._register_event_handler("on_frame_reached_upstream") - self._register_event_handler("on_frame_reached_downstream") - self._register_event_handler("on_idle_timeout") - self._register_event_handler("on_pipeline_started") - self._register_event_handler("on_pipeline_finished") - self._register_event_handler("on_pipeline_error") - - # Bridge pipeline lifecycle to the BaseTask lifecycle so the bus - # registry sees this task as ready/finished. - @self.event_handler("on_pipeline_started") - async def on_started(_task, _frame): - await self.start() - - @self.event_handler("on_pipeline_finished") - async def on_finished(_task, _frame): - await self.stop() - - @property - def params(self) -> PipelineParams: - """Get the pipeline parameters for this task. - - Returns: - The pipeline parameters configuration. - """ - return self._params - - @property - def bridged(self) -> bool: - """Whether this pipeline is bridged onto the bus.""" - return self._bridged is not None - - @property - def app_resources(self) -> Any: - """Get the application-defined resources passed to this task. - - This is the same object passed to the constructor as - ``app_resources``. Tool handlers can also access it via - ``FunctionCallParams.app_resources``. The framework returns the - original reference; mutations are visible to all callers. - - Returns: - The application-defined resources, or ``None`` if none were - passed. - """ - return self._app_resources - - @property - def pipeline(self) -> BasePipeline: - """Get the full pipeline managed by this pipeline task. - - This will also include any internal processors added by the pipeline task. - - Returns: - The pipeline managed by the pipeline task. - """ - return self._pipeline - - @property - def turn_tracking_observer(self) -> TurnTrackingObserver | None: - """Get the turn tracking observer if enabled. - - Returns: - The turn tracking observer instance or None if not enabled. - """ - return self._turn_tracking_observer - - @property - def turn_trace_observer(self) -> TurnTraceObserver | None: - """Get the turn trace observer if enabled. - - Returns: - The turn trace observer instance or None if not enabled. - """ - return self._turn_trace_observer - - @property - def rtvi(self) -> RTVIProcessor: - """Get the RTVI processor if RTVI is enabled. - - Returns: - The RTVI processor added to the pipeline when RTVI is enabled. - """ - if not self._rtvi: - raise Exception(f"{self} RTVI is not enabled.") - return self._rtvi - - @property - def reached_upstream_types(self) -> tuple[type[Frame], ...]: - """Get the currently configured upstream frame type filters. - - Returns: - Tuple of frame types that trigger the on_frame_reached_upstream event. - """ - return tuple(self._reached_upstream_types) - - @property - def reached_downstream_types(self) -> tuple[type[Frame], ...]: - """Get the currently configured downstream frame type filters. - - Returns: - Tuple of frame types that trigger the on_frame_reached_downstream event. - """ - return tuple(self._reached_downstream_types) - - def add_observer(self, observer: BaseObserver): - """Add an observer to monitor pipeline execution. - - Args: - observer: The observer to add to the pipeline monitoring. - """ - self._observer.add_observer(observer) - - async def remove_observer(self, observer: BaseObserver): - """Remove an observer from pipeline monitoring. - - Args: - observer: The observer to remove from pipeline monitoring. - """ - await self._observer.remove_observer(observer) - - def set_reached_upstream_filter(self, types: tuple[type[Frame], ...]): - """Set which frame types trigger the on_frame_reached_upstream event. - - Args: - types: Tuple of frame types to monitor for upstream events. - """ - self._reached_upstream_types = set(types) - - def set_reached_downstream_filter(self, types: tuple[type[Frame], ...]): - """Set which frame types trigger the on_frame_reached_downstream event. - - Args: - types: Tuple of frame types to monitor for downstream events. - """ - self._reached_downstream_types = set(types) - - def add_reached_upstream_filter(self, types: tuple[type[Frame], ...]): - """Add frame types to trigger the on_frame_reached_upstream event. - - Args: - types: Tuple of frame types to add to upstream monitoring. - """ - self._reached_upstream_types.update(types) - - def add_reached_downstream_filter(self, types: tuple[type[Frame], ...]): - """Add frame types to trigger the on_frame_reached_downstream event. - - Args: - types: Tuple of frame types to add to downstream monitoring. - """ - self._reached_downstream_types.update(types) - - def has_finished(self) -> bool: - """Check if the pipeline task has finished execution. - - This indicates whether the tasks has finished, meaninig all processors - have stopped. - - Returns: - True if all processors have stopped and the task is complete. - """ - return self._finished - - async def stop_when_done(self): - """Schedule the pipeline to stop after processing all queued frames. - - Sends an EndFrame to gracefully terminate the pipeline once all - current processing is complete. - """ - logger.debug(f"Task {self} scheduled to stop when done") - await self.queue_frame(EndFrame()) - - async def cancel(self, *, reason: str | None = None): - """Request the running pipeline to cancel. - - Args: - reason: Optional reason to indicate why the pipeline is being cancelled. - """ - if not self._finished: - await self._cancel(reason=reason) - - async def run(self, params: PipelineTaskParams): - """Start and manage the pipeline execution until completion or cancellation. - - Args: - params: Configuration parameters for pipeline execution. - """ - if self.has_finished(): - return - - # Setup processors. - await self._setup(params) - - # Create all main tasks and wait for the main push task. This is the - # task that pushes frames to the very beginning of our pipeline (i.e. to - # our controlled source processor). - await self._create_tasks() - - try: - # Wait for pipeline to finish. - await self._wait_for_pipeline_finished() - except asyncio.CancelledError: - logger.debug(f"Pipeline task {self} got cancelled from outside...") - # We have been cancelled from outside, let's just cancel everything. - await self._cancel() - # Wait again for pipeline to finish. This time we have really - # cancelled, so it should really finish. - await self._wait_for_pipeline_finished() - # Re-raise in case there's more cleanup to do. - raise - finally: - # We can reach this point for different reasons: - # - # 1. The pipeline task has finished (try case). - # 2. By an asyncio task cancellation (except case). - logger.debug(f"Pipeline task {self} is finishing...") - await self._cancel_tasks() - if self._check_dangling_tasks: - self._print_dangling_tasks() - self._finished = True - logger.debug(f"Pipeline task {self} has finished") - - async def queue_frame( - self, frame: Frame, direction: FrameDirection = FrameDirection.DOWNSTREAM - ): - """Queue a single frame to be pushed through the pipeline. - - Downstream frames are pushed from the beginning of the pipeline. - Upstream frames are pushed from the end of the pipeline. - - Args: - frame: The frame to be processed. - direction: The direction to push the frame. Defaults to downstream. - """ - if direction == FrameDirection.DOWNSTREAM: - await self._push_queue.put(frame) - else: - await self._sink.queue_frame(frame, direction) - - async def queue_frames( - self, - frames: Iterable[Frame] | AsyncIterable[Frame], - direction: FrameDirection = FrameDirection.DOWNSTREAM, - ): - """Queue multiple frames to be pushed through the pipeline. - - Downstream frames are pushed from the beginning of the pipeline. - Upstream frames are pushed from the end of the pipeline. - - Args: - frames: An iterable or async iterable of frames to be processed. - direction: The direction to push the frames. Defaults to downstream. - """ - if isinstance(frames, AsyncIterable): - async for frame in frames: - await self.queue_frame(frame, direction) - elif isinstance(frames, Iterable): - for frame in frames: - await self.queue_frame(frame, direction) - - async def _cancel(self, *, reason: str | None = None): - """Internal cancellation logic for the pipeline task. - - Args: - reason: Optional reason to indicate why the pipeline is being cancelled. - """ - if not self._cancelled: - logger.debug(f"Cancelling pipeline task {self}") - self._cancelled = True - await self.queue_frame(CancelFrame(reason=reason)) - - async def _create_tasks(self): - """Create and start all pipeline processing tasks.""" - self._process_push_task = self.create_task(self._process_push_queue()) - return self._process_push_task - - def _maybe_start_heartbeat_tasks(self): - """Start heartbeat tasks if heartbeats are enabled and not already running.""" - if self._params.enable_heartbeats and self._heartbeat_push_task is None: - self._heartbeat_push_task = self.create_task(self._heartbeat_push_handler()) - self._heartbeat_monitor_task = self.create_task(self._heartbeat_monitor_handler()) - - def _maybe_start_idle_task(self): - """Start idle monitoring task if idle timeout is configured.""" - if self._idle_timeout_secs: - self._idle_monitor_task = self.create_task(self._idle_monitor_handler()) - - async def _cancel_tasks(self): - """Cancel all running pipeline tasks.""" - if self._process_push_task: - await self.cancel_task(self._process_push_task) - self._process_push_task = None - - await self._maybe_cancel_heartbeat_tasks() - await self._maybe_cancel_idle_task() - - async def _maybe_cancel_heartbeat_tasks(self): - """Cancel heartbeat tasks if they are running.""" - if not self._params.enable_heartbeats: - return - - if self._heartbeat_push_task: - await self.cancel_task(self._heartbeat_push_task) - self._heartbeat_push_task = None - - if self._heartbeat_monitor_task: - await self.cancel_task(self._heartbeat_monitor_task) - self._heartbeat_monitor_task = None - - async def _maybe_cancel_idle_task(self): - """Cancel idle monitoring task if it is running.""" - if self._idle_monitor_task: - await self.cancel_task(self._idle_monitor_task) - self._idle_monitor_task = None - - def _initial_metrics_frame(self) -> MetricsFrame: - """Create an initial metrics frame with zero values for all processors.""" - processors = self._pipeline.processors_with_metrics() - data = [] - for p in processors: - data.append(TTFBMetricsData(processor=p.name, value=0.0)) - data.append(ProcessingMetricsData(processor=p.name, value=0.0)) - return MetricsFrame(data=data) - - async def _wait_for_pipeline_start(self, frame: Frame): - """Wait for the specified start frame to reach the end of the pipeline.""" - logger.debug(f"{self}: Starting. Waiting for {frame} to reach the end of the pipeline...") - await self._pipeline_start_event.wait() - self._pipeline_start_event.clear() - logger.debug(f"{self}: {frame} reached the end of the pipeline, pipeline is now ready.") - - async def _wait_for_pipeline_end(self, frame: Frame): - """Wait for the specified frame to reach the end of the pipeline.""" - - async def wait_for_cancel(): - try: - await asyncio.wait_for( - self._pipeline_end_event.wait(), timeout=self._cancel_timeout_secs - ) - logger.debug(f"{self}: {frame} reached the end of the pipeline.") - except TimeoutError: - logger.warning( - f"{self}: timeout waiting for {frame} to reach the end of the pipeline (being blocked somewhere?)." - ) - finally: - await self._call_event_handler("on_pipeline_finished", frame) - - logger.debug(f"{self}: Closing. Waiting for {frame} to reach the end of the pipeline...") - - if isinstance(frame, CancelFrame): - await wait_for_cancel() - else: - await self._pipeline_end_event.wait() - logger.debug(f"{self}: {frame} reached the end of the pipeline, pipeline is closing.") - - self._pipeline_end_event.clear() - - # We are really done. Setting ``_finished_event`` makes - # ``BaseTask.wait()`` resolve for callers awaiting this task. - self._finished_event.set() - - async def _wait_for_pipeline_finished(self): - await self._finished_event.wait() - # Make sure we wait for the main task to complete. - if self._process_push_task: - await self._process_push_task - self._process_push_task = None - - async def _setup(self, params: PipelineTaskParams): - """Set up the pipeline task and all processors.""" - await super().setup(self._pipeline_task_manager) - - if self._bus is not None: - await self._bus.subscribe(self) - - mgr_params = TaskManagerParams(loop=params.loop) - self.task_manager.setup(mgr_params) - - setup = FrameProcessorSetup( - clock=self._clock, - task_manager=self.task_manager, - observer=self._observer, - pipeline_task=self, - # Populate the deprecated `tool_resources` field for backwards - # compatibility with custom FrameProcessor subclasses whose - # ``setup()`` overrides still read it. Reading the field emits a - # DeprecationWarning; new code should read - # ``setup.pipeline_task.app_resources`` instead. - tool_resources=self._app_resources, - ) - await self._pipeline.setup(setup) - - # Do any additional pipeline task setup externally. - await self._load_setup_files() - - # Start task observer. - await self._observer.setup(self.task_manager) - await self._observer.start() - - async def _cleanup(self, cleanup_pipeline: bool): - """Clean up the pipeline task and processors.""" - # Cleanup base object. - await self.cleanup() - - # Cleanup observers. - await self._observer.stop() - await self._observer.cleanup() - - # End conversation tracing if it's active - this will also close any active turn span - if self._enable_tracing and self._turn_trace_observer: - self._turn_trace_observer.end_conversation_tracing() - - # Cleanup pipeline processors. - if cleanup_pipeline: - await self._pipeline.cleanup() - - async def _handle_task_end(self, message: BusEndTaskMessage) -> None: - """End the pipeline after propagating end to children. - - Drives shutdown through the pipeline (``EndFrame``) so - ``_finished_event`` fires once the frame drains through the - sink, rather than calling ``stop()`` directly. - """ - logger.debug(f"Task '{self}': received end") - await self._propagate_end_to_children(message) - await self.queue_frame(EndFrame(reason=message.reason)) - - async def _handle_task_cancel(self, message: BusCancelTaskMessage) -> None: - """Cancel the pipeline after propagating cancel to children. - - Drives shutdown through the pipeline (``CancelFrame``) so - ``_finished_event`` fires once the frame drains, rather than - calling ``stop()`` directly. - """ - logger.debug(f"Task '{self}': received cancel") - await self._propagate_cancel_to_children(message) - await self.cancel(reason=message.reason) - - async def _process_push_queue(self): - """Process frames from the push queue and send them through the pipeline. - - This is the task that runs the pipeline for the first time by sending - a StartFrame and by pushing any other frames queued by the user. It runs - until the tasks is cancelled or stopped (e.g. with an EndFrame). - """ - self._clock.start() - - self._maybe_start_idle_task() - - start_frame = StartFrame( - audio_in_sample_rate=self._params.audio_in_sample_rate, - audio_out_sample_rate=self._params.audio_out_sample_rate, - enable_metrics=self._params.enable_metrics, - enable_tracing=self._enable_tracing, - enable_usage_metrics=self._params.enable_usage_metrics, - report_only_initial_ttfb=self._params.report_only_initial_ttfb, - tracing_context=self._tracing_context, - ) - start_frame.metadata = self._create_start_metadata() - await self._pipeline.queue_frame(start_frame) - - # Wait for the pipeline to be started before pushing any other frame. - await self._wait_for_pipeline_start(start_frame) - - if self._params.enable_metrics and self._params.send_initial_empty_metrics: - await self._pipeline.queue_frame(self._initial_metrics_frame()) - - running = True - cleanup_pipeline = True - while running: - frame = await self._push_queue.get() - await self._pipeline.queue_frame(frame) - if isinstance(frame, (CancelFrame, EndFrame, StopFrame)): - await self._wait_for_pipeline_end(frame) - running = not isinstance(frame, (CancelFrame, EndFrame, StopFrame)) - cleanup_pipeline = not isinstance(frame, StopFrame) - self._push_queue.task_done() - await self._cleanup(cleanup_pipeline) - - async def _source_push_frame(self, frame: Frame, direction: FrameDirection): - """Process frames coming upstream from the pipeline. - - This is the task that processes frames coming upstream from the - pipeline. These frames might indicate, for example, that we want the - pipeline to be stopped (e.g. EndTaskFrame) in which case we would send - an EndFrame down the pipeline. - """ - if isinstance(frame, tuple(self._reached_upstream_types)): - await self._call_event_handler("on_frame_reached_upstream", frame) - - if isinstance(frame, EndTaskFrame): - # Tell the task we should end nicely. - logger.debug(f"{self}: received end task frame upstream {frame}") - await self.queue_frame(EndFrame(reason=frame.reason)) - elif isinstance(frame, CancelTaskFrame): - # Tell the task we should end right away. - logger.debug(f"{self}: received cancel task frame upstream {frame}") - await self.queue_frame(CancelFrame(reason=frame.reason)) - elif isinstance(frame, StopTaskFrame): - # Tell the task we should stop nicely. - logger.debug(f"{self}: received stop task frame upstream {frame}") - await self.queue_frame(StopFrame()) - elif isinstance(frame, InterruptionTaskFrame): - # Tell the task we should interrupt the pipeline. Note that we are - # bypassing the push queue and directly queue into the - # pipeline. This is in case the push task is blocked waiting for a - # pipeline-ending frame to finish traversing the pipeline. - logger.debug(f"{self}: received interruption task frame upstream {frame}") - await self._pipeline.queue_frame(InterruptionFrame()) - elif isinstance(frame, ErrorFrame): - await self._call_event_handler("on_pipeline_error", frame) - if frame.fatal: - logger.error(f"A fatal error occurred: {frame}") - # Cancel all tasks downstream. - await self.queue_frame(CancelFrame()) - else: - logger.warning(f"{self}: Something went wrong: {frame}") - - async def _sink_push_frame(self, frame: Frame, direction: FrameDirection): - """Process frames coming downstream from the pipeline. - - This tasks process frames coming downstream from the pipeline. For - example, heartbeat frames or an EndFrame which would indicate all - processors have handled the EndFrame and therefore we can exit the task - cleanly. - """ - if isinstance(frame, tuple(self._reached_downstream_types)): - await self._call_event_handler("on_frame_reached_downstream", frame) - - if isinstance(frame, StartFrame): - await self._call_event_handler("on_pipeline_started", frame) - await self._observer.on_pipeline_started() - - # Start heartbeat tasks now that StartFrame has been processed - # by all processors in the pipeline - self._maybe_start_heartbeat_tasks() - - self._pipeline_start_event.set() - elif isinstance(frame, EndFrame): - await self._call_event_handler("on_pipeline_finished", frame) - self._pipeline_end_event.set() - elif isinstance(frame, StopFrame): - await self._call_event_handler("on_pipeline_finished", frame) - self._pipeline_end_event.set() - elif isinstance(frame, CancelFrame): - self._pipeline_end_event.set() - elif isinstance(frame, HeartbeatFrame): - await self._heartbeat_queue.put(frame) - elif isinstance(frame, EndTaskFrame): - logger.debug(f"{self}: received end task frame downstream {frame}") - await self.queue_frame(EndTaskFrame(reason=frame.reason), FrameDirection.UPSTREAM) - elif isinstance(frame, StopTaskFrame): - logger.debug(f"{self}: received stop task frame downstream {frame}") - await self.queue_frame(StopTaskFrame(), FrameDirection.UPSTREAM) - elif isinstance(frame, CancelTaskFrame): - logger.debug(f"{self}: received cancel task frame downstream {frame}") - await self.queue_frame(CancelTaskFrame(reason=frame.reason), FrameDirection.UPSTREAM) - elif isinstance(frame, InterruptionTaskFrame): - logger.debug(f"{self}: received interruption task frame downstream {frame}") - await self.queue_frame(InterruptionTaskFrame(), FrameDirection.UPSTREAM) - - async def _heartbeat_push_handler(self): - """Push heartbeat frames at regular intervals.""" - while True: - # Don't use `queue_frame()` because if an EndFrame is queued the - # task will just stop waiting for the pipeline to finish not - # allowing more frames to be pushed. - await self._pipeline.queue_frame(HeartbeatFrame(timestamp=self._clock.get_time())) - await asyncio.sleep(self._params.heartbeats_period_secs) - - async def _heartbeat_monitor_handler(self): - """Monitor heartbeat frames for processing time and timeout detection. - - This task monitors heartbeat frames. If a heartbeat frame has not - been received for a long period a warning will be logged. It also logs - the time that a heartbeat frame takes to processes, that is how long it - takes for the heartbeat frame to traverse all the pipeline. - """ - wait_time = self._params.heartbeats_monitor_secs - while True: - try: - frame = await asyncio.wait_for(self._heartbeat_queue.get(), timeout=wait_time) - process_time = (self._clock.get_time() - frame.timestamp) / 1_000_000_000 - logger.trace(f"{self}: heartbeat frame processed in {process_time} seconds") - self._heartbeat_queue.task_done() - except TimeoutError: - logger.warning( - f"{self}: heartbeat frame not received for more than {wait_time} seconds" - ) - - async def _idle_monitor_handler(self): - """Monitor pipeline activity and detect idle conditions. - - Tracks frame activity and triggers idle timeout events when the - pipeline hasn't received relevant frames within the timeout period. - - Note: Heartbeats are excluded from idle detection. - """ - running = True - while running: - try: - await asyncio.wait_for(self._idle_event.wait(), timeout=self._idle_timeout_secs) - self._idle_event.clear() - except TimeoutError: - running = await self._idle_timeout_detected() - - async def _idle_timeout_detected(self) -> bool: - """Handle idle timeout detection and optional cancellation. - - Returns: - Whether the pipeline task should continue running. - """ - # If we are cancelling, just exit the task. - if self._cancelled: - return False - - logger.warning("Idle timeout detected.") - await self._call_event_handler("on_idle_timeout") - if self._cancel_on_idle_timeout: - logger.warning(f"Idle pipeline detected, cancelling pipeline task...") - await self.cancel() - return False - return True - - async def _load_setup_files(self): - """Run ``setup_pipeline_task`` from each file in ``PIPECAT_SETUP_FILES``. - - A setup file may define ``setup_pipeline_task(task)`` to attach event - handlers, observers, or other per-task wiring. - """ - await run_setup_hook(target=self, function_name="setup_pipeline_task") - - def _print_dangling_tasks(self): - """Log any dangling tasks that haven't been properly cleaned up.""" - tasks = [t.get_name() for t in self.task_manager.current_tasks()] - if tasks: - logger.warning(f"{self} dangling tasks detected: {tasks}") - - def _create_start_metadata(self) -> dict[str, Any]: - """Build and return start metadata including user-provided values.""" - start_metadata = {} - - # Update with user provided metadata. - start_metadata.update(self._params.start_metadata) - - return start_metadata - - def _find_processor(self, processor: FrameProcessor, processor_type: type[T]) -> T | None: - """Recursively find a processor of the given type in the pipeline.""" - if isinstance(processor, processor_type): - return processor - - for p in processor.processors: - found = self._find_processor(p, processor_type) - if found: - return found - return None +__all__ = [ + "IdleFrameObserver", + "PipelineParams", + "PipelineTask", + "PipelineTaskParams", + "PipelineWorker", + "PipelineWorkerParams", +] diff --git a/src/pipecat/pipeline/task_ready_decorator.py b/src/pipecat/pipeline/task_ready_decorator.py deleted file mode 100644 index 25933e32b..000000000 --- a/src/pipecat/pipeline/task_ready_decorator.py +++ /dev/null @@ -1,61 +0,0 @@ -# -# Copyright (c) 2026, Daily -# -# SPDX-License-Identifier: BSD 2-Clause License -# - -"""Decorator for marking methods as task-ready handlers.""" - -from collections.abc import Callable - - -def task_ready(*, name: str): - """Mark a method as a handler for a specific task becoming ready. - - Decorated methods are automatically collected by `BaseTask` at - initialization. When the task starts, it calls `watch_task` for - each decorated handler. When the watched task registers, the - decorated method is called with the ready data. - - Example:: - - @task_ready(name="greeter") - async def on_greeter_ready(self, data: TaskReadyData) -> None: - await self.activate_task("greeter", args=...) - - Args: - name: The name of the task to watch. - """ - - def decorator(fn): - fn.task_ready_name = name - return fn - - return decorator - - -def _collect_task_ready_handlers(obj) -> dict: - """Collect all ``@task_ready`` decorated bound methods from an object. - - Returns a dict mapping task name to the bound method. - - Raises: - ValueError: If two handlers watch the same task name. - """ - seen: set[str] = set() - handlers: dict[str, Callable] = {} - for cls in type(obj).__mro__: - for attr_name, val in cls.__dict__.items(): - if attr_name in seen: - continue - seen.add(attr_name) - if callable(val) and hasattr(val, "task_ready_name"): - task_name = val.task_ready_name - if task_name in handlers: - existing = handlers[task_name].__name__ - raise ValueError( - f"Duplicate @task_ready handler for '{task_name}': " - f"'{attr_name}' conflicts with '{existing}'" - ) - handlers[task_name] = getattr(obj, attr_name) - return handlers diff --git a/src/pipecat/pipeline/utils.py b/src/pipecat/pipeline/utils.py index f695acb58..5c5dc2872 100644 --- a/src/pipecat/pipeline/utils.py +++ b/src/pipecat/pipeline/utils.py @@ -10,9 +10,9 @@ Each file listed in the ``PIPECAT_SETUP_FILES`` environment variable (colon separated) may define one or both of the following async functions: - ``setup_pipeline_runner(runner)`` — invoked once per :class:`PipelineRunner` - before its spawned tasks start. -- ``setup_pipeline_task(task)`` — invoked once per :class:`PipelineTask` while - the task sets up its pipeline. + before its spawned workers start. +- ``setup_pipeline_worker(worker)`` — invoked once per :class:`PipelineWorker` while + the worker sets up its pipeline. Setup files are imported at most once per process; module-level state (for example, a shared debugger instance referenced by both hooks) is preserved diff --git a/src/pipecat/pipeline/worker.py b/src/pipecat/pipeline/worker.py new file mode 100644 index 000000000..c0e0feee5 --- /dev/null +++ b/src/pipecat/pipeline/worker.py @@ -0,0 +1,1136 @@ +# +# Copyright (c) 2024-2026, Daily +# +# SPDX-License-Identifier: BSD 2-Clause License +# + +"""Pipeline worker implementation for managing frame processing pipelines. + +This module provides the main PipelineWorker class that orchestrates pipeline +execution, frame routing, lifecycle management, and monitoring capabilities +including heartbeats, idle detection, and observer integration. +""" + +import asyncio +import warnings +from collections.abc import AsyncIterable, Iterable +from dataclasses import dataclass +from typing import Any, TypeVar + +from loguru import logger +from pydantic import BaseModel, ConfigDict, Field + +from pipecat.bus import BusCancelWorkerMessage, BusEndWorkerMessage, WorkerBus +from pipecat.bus.bridge_processor import _BusEdgeProcessor +from pipecat.clocks.base_clock import BaseClock +from pipecat.clocks.system_clock import SystemClock +from pipecat.frames.frames import ( + BotSpeakingFrame, + CancelFrame, + CancelTaskFrame, + EndFrame, + EndTaskFrame, + ErrorFrame, + Frame, + HeartbeatFrame, + InterruptionFrame, + InterruptionTaskFrame, + MetricsFrame, + StartFrame, + StopFrame, + StopTaskFrame, + UserSpeakingFrame, +) +from pipecat.metrics.metrics import ProcessingMetricsData, TTFBMetricsData +from pipecat.observers.base_observer import BaseObserver, FramePushed +from pipecat.observers.turn_tracking_observer import TurnTrackingObserver +from pipecat.observers.user_bot_latency_observer import UserBotLatencyObserver +from pipecat.pipeline.base_pipeline import BasePipeline +from pipecat.pipeline.base_worker import BaseWorker +from pipecat.pipeline.pipeline import Pipeline, PipelineSink, PipelineSource +from pipecat.pipeline.utils import run_setup_hook +from pipecat.pipeline.worker_observer import WorkerObserver +from pipecat.processors.frame_processor import FrameDirection, FrameProcessor, FrameProcessorSetup +from pipecat.processors.frameworks.rtvi import RTVIObserver, RTVIObserverParams, RTVIProcessor +from pipecat.utils.asyncio.task_manager import BaseTaskManager, TaskManager, TaskManagerParams +from pipecat.utils.tracing.setup import is_tracing_available +from pipecat.utils.tracing.tracing_context import TracingContext +from pipecat.utils.tracing.turn_trace_observer import TurnTraceObserver + +HEARTBEAT_SECS = 1.0 +HEARTBEAT_MONITOR_SECS = 10.0 + +IDLE_TIMEOUT_SECS = 300 + +CANCEL_TIMEOUT_SECS = 20.0 + + +T = TypeVar("T") + + +@dataclass +class PipelineWorkerParams: + """Configuration parameters for pipeline worker execution. + + Parameters: + loop: The asyncio event loop to use for worker execution. + """ + + loop: asyncio.AbstractEventLoop + + +class IdleFrameObserver(BaseObserver): + """Idle timeout observer. + + This observer waits for specific frames being generated in the pipeline. If + the frames are generated the given asyncio event is set. If the event is not + set it means the pipeline is probably idle. + + """ + + def __init__(self, *, idle_event: asyncio.Event, idle_timeout_frames: tuple[type[Frame], ...]): + """Initialize the observer. + + Args: + idle_event: The event to set if the idle timeout frames are being pushed. + idle_timeout_frames: A tuple with the frames that should set the event when received + """ + super().__init__() + self._idle_event = idle_event + self._idle_timeout_frames = idle_timeout_frames + self._processed_frames = set() + + async def on_push_frame(self, data: FramePushed): + """Callback executed when a frame is pushed in the pipeline. + + Args: + data: The frame push event data. + """ + # Skip already processed frames + if data.frame.id in self._processed_frames: + return + + self._processed_frames.add(data.frame.id) + + if isinstance(data.frame, StartFrame) or isinstance(data.frame, self._idle_timeout_frames): + self._idle_event.set() + + +class PipelineParams(BaseModel): + """Configuration parameters for pipeline execution. + + These parameters are usually passed to all frame processors through + StartFrame. For other generic pipeline worker parameters use PipelineWorker + constructor arguments instead. + + Parameters: + audio_in_sample_rate: Input audio sample rate in Hz. + audio_out_sample_rate: Output audio sample rate in Hz. + enable_heartbeats: Whether to enable heartbeat monitoring. + enable_metrics: Whether to enable metrics collection. + enable_usage_metrics: Whether to enable usage metrics. + heartbeats_period_secs: Period between heartbeats in seconds. + heartbeats_monitor_secs: Timeout (in seconds) before warning about + missed heartbeats. Defaults to 10 seconds. + report_only_initial_ttfb: Whether to report only initial time to first byte. + send_initial_empty_metrics: Whether to send initial empty metrics. + start_metadata: Additional metadata for pipeline start. + """ + + model_config = ConfigDict(arbitrary_types_allowed=True) + + audio_in_sample_rate: int = 16000 + audio_out_sample_rate: int = 24000 + enable_heartbeats: bool = False + enable_metrics: bool = False + enable_usage_metrics: bool = False + heartbeats_period_secs: float = HEARTBEAT_SECS + heartbeats_monitor_secs: float = HEARTBEAT_MONITOR_SECS + report_only_initial_ttfb: bool = False + send_initial_empty_metrics: bool = True + start_metadata: dict[str, Any] = Field(default_factory=dict) + + +class PipelineWorker(BaseWorker): + """Manages the execution of a pipeline, handling frame processing and worker lifecycle. + + This class orchestrates pipeline execution with comprehensive monitoring, + event handling, and lifecycle management. It provides event handlers for + various pipeline states and frame types, idle detection, heartbeat monitoring, + and observer integration. + + Event handlers available: + + - on_frame_reached_upstream: Called when upstream frames reach the source + - on_frame_reached_downstream: Called when downstream frames reach the sink + - on_idle_timeout: Called when pipeline is idle beyond timeout threshold + - on_pipeline_started: Called when pipeline starts with StartFrame + - on_pipeline_finished: Called after the pipeline has reached any terminal state. + This includes: + + - StopFrame: pipeline was stopped (processors keep connections open) + - EndFrame: pipeline ended normally + - CancelFrame: pipeline was cancelled + + Use this event for cleanup, logging, or post-processing tasks. Users can inspect + the frame if they need to handle specific cases. + + - on_pipeline_error: Called when an error occurs with ErrorFrame + + Example:: + + @worker.event_handler("on_frame_reached_upstream") + async def on_frame_reached_upstream(worker, frame): + ... + + @worker.event_handler("on_idle_timeout") + async def on_pipeline_idle_timeout(worker): + ... + + @worker.event_handler("on_pipeline_started") + async def on_pipeline_started(worker, frame): + ... + + @worker.event_handler("on_pipeline_finished") + async def on_pipeline_finished(worker, frame): + ... + + @worker.event_handler("on_pipeline_error") + async def on_pipeline_error(worker, frame): + ... + """ + + def __init__( + self, + pipeline: BasePipeline, + *, + additional_span_attributes: dict | None = None, + app_resources: Any = None, + bridged: tuple[str, ...] | None = None, + cancel_on_idle_timeout: bool = True, + cancel_timeout_secs: float = CANCEL_TIMEOUT_SECS, + check_dangling_tasks: bool = True, + clock: BaseClock | None = None, + conversation_id: str | None = None, + enable_tracing: bool = False, + enable_turn_tracking: bool = True, + enable_rtvi: bool = True, + exclude_frames: tuple[type[Frame], ...] | None = None, + idle_timeout_frames: tuple[type[Frame], ...] = (BotSpeakingFrame, UserSpeakingFrame), + idle_timeout_secs: float | None = IDLE_TIMEOUT_SECS, + name: str | None = None, + observers: list[BaseObserver] | None = None, + params: PipelineParams | None = None, + rtvi_processor: RTVIProcessor | None = None, + rtvi_observer_params: RTVIObserverParams | None = None, + task_manager: BaseTaskManager | None = None, + tool_resources: Any = None, + ): + """Initialize the PipelineWorker. + + Args: + pipeline: The pipeline to execute. + additional_span_attributes: Optional dictionary of attributes to propagate as + OpenTelemetry conversation span attributes. + app_resources: Optional application-defined bag of anything your + application code may want to share across this session (DB + handles, HTTP clients, etc.), passed by reference. Pipecat + passes it through untouched and exposes it on the worker itself + as ``worker.app_resources`` and passes it to tool handlers as + ``FunctionCallParams.app_resources``. The framework never + copies or clears this object; the caller retains their handle + and can read any mutations after the worker finishes. + bridged: Bridge configuration. ``None`` means the pipeline + is not bridged. An empty tuple ``()`` wraps the pipeline + with bus edge processors that accept frames from all + bridges. A tuple of names like ``("voice",)`` accepts + only frames from those bridges. The bus comes from + :meth:`attach` (called by the runner). + cancel_on_idle_timeout: Whether the pipeline worker should be cancelled if + the idle timeout is reached. + cancel_timeout_secs: Timeout (in seconds) to wait for cancellation to happen + cleanly. + check_dangling_tasks: Whether to check for processors' tasks finishing properly. + clock: Clock implementation for timing operations. + conversation_id: Optional custom ID for the conversation. + enable_rtvi: Whether to automatically add RTVI support to the pipeline. + enable_tracing: Whether to enable tracing. + enable_turn_tracking: Whether to enable turn tracking. + exclude_frames: When ``bridged`` is set, extra frame types + that should not cross the bus (lifecycle frames are + always excluded). + idle_timeout_frames: A tuple with the frames that should trigger an idle + timeout if not received within `idle_timeout_seconds`. + idle_timeout_secs: Timeout (in seconds) to consider pipeline idle or + None. If a pipeline is idle the pipeline worker will be cancelled + automatically. + name: Optional worker name (used for worker-style addressing on the bus). + observers: List of observers for monitoring pipeline execution. + params: Configuration parameters for the pipeline. + rtvi_observer_params: The RTVI observer parameter to use if RTVI is enabled. + rtvi_processor: The RTVI processor to add if RTVI is enabled. + task_manager: Optional worker manager for handling asyncio tasks. + tool_resources: Deprecated alias for ``app_resources``. + + .. deprecated:: 1.2.0 + Use ``app_resources`` instead. ``tool_resources`` will be + removed in a future version. + """ + super().__init__(name=name) + self._bridged = bridged + if tool_resources is not None: + with warnings.catch_warnings(): + warnings.simplefilter("always") + warnings.warn( + "`PipelineWorker(tool_resources=...)` is deprecated since 1.2.0, " + "use `app_resources` instead.", + DeprecationWarning, + stacklevel=2, + ) + if app_resources is None: + app_resources = tool_resources + self._params = params or PipelineParams() + self._additional_span_attributes = additional_span_attributes or {} + self._cancel_on_idle_timeout = cancel_on_idle_timeout + self._cancel_timeout_secs = cancel_timeout_secs + self._check_dangling_tasks = check_dangling_tasks + self._clock = clock or SystemClock() + self._conversation_id = conversation_id + self._enable_tracing = enable_tracing and is_tracing_available() + self._enable_turn_tracking = enable_turn_tracking + self._idle_timeout_secs = idle_timeout_secs + self._app_resources = app_resources + observers = observers or [] + self._turn_tracking_observer: TurnTrackingObserver | None = None + self._user_bot_latency_observer: UserBotLatencyObserver | None = None + self._turn_trace_observer: TurnTraceObserver | None = None + self._tracing_context: TracingContext | None = None + if self._enable_turn_tracking: + self._turn_tracking_observer = TurnTrackingObserver() + observers.append(self._turn_tracking_observer) + if self._enable_tracing and self._turn_tracking_observer: + # Create pipeline-scoped tracing context + self._tracing_context = TracingContext() + # Create latency observer for tracing + self._user_bot_latency_observer = UserBotLatencyObserver() + observers.append(self._user_bot_latency_observer) + # Create turn trace observer with latency tracking + self._turn_trace_observer = TurnTraceObserver( + self._turn_tracking_observer, + latency_tracker=self._user_bot_latency_observer, + conversation_id=self._conversation_id, + additional_span_attributes=self._additional_span_attributes, + tracing_context=self._tracing_context, + ) + observers.append(self._turn_trace_observer) + + self._finished = False + self._cancelled = False + + # This worker maneger will handle all the asyncio tasks created by this + # PipelineWorker and its frame processors. + self._pipeline_task_manager = task_manager or TaskManager() + + # This queue is the queue used to push frames to the pipeline. + self._push_queue = asyncio.Queue() + self._process_push_task: asyncio.Task | None = None + + # This is the heartbeat queue. When a heartbeat frame is received in the + # down queue we add it to the heartbeat queue for processing. + self._heartbeat_queue = asyncio.Queue() + self._heartbeat_push_task: asyncio.Task | None = None + self._heartbeat_monitor_task: asyncio.Task | None = None + + # RTVI support + self._rtvi = None + prepend_rtvi = False + external_rtvi = self._find_processor(pipeline, RTVIProcessor) + external_observer_found = any(isinstance(o, RTVIObserver) for o in observers) + + if external_rtvi and not external_observer_found: + logger.error( + f"{self}: RTVIProcessor found in pipeline but no RTVIObserver in observers. " + "Make sure to add both." + ) + elif not external_rtvi and external_observer_found: + logger.error( + f"{self}: RTVIObserver found in observers but no RTVIProcessor in pipeline. " + "Make sure to add both." + ) + elif external_rtvi and external_observer_found: + logger.warning( + f"{self}: RTVIProcessor and RTVIObserver found, skipping default ones. " + "They are both added by default, no need to add them yourself." + ) + self._rtvi = external_rtvi + elif enable_rtvi: + self._rtvi = rtvi_processor or RTVIProcessor() + observers.append(self._rtvi.create_rtvi_observer(params=rtvi_observer_params)) + prepend_rtvi = True + + if self._rtvi: + # Automatically call RTVIProcessor.set_bot_ready() + @self.rtvi.event_handler("on_client_ready") + async def on_client_ready(rtvi: RTVIProcessor): + await rtvi.set_bot_ready() + + # This is the idle event. When selected frames are pushed from any + # processor we consider the pipeline is not idle. We use an observer + # which will be listening any part of the pipeline. + self._idle_event = asyncio.Event() + self._idle_monitor_task: asyncio.Task | None = None + if self._idle_timeout_secs: + idle_frame_observer = IdleFrameObserver( + idle_event=self._idle_event, + idle_timeout_frames=idle_timeout_frames, + ) + observers.append(idle_frame_observer) + + # This event is used to indicate the StartFrame has been received at the + # end of the pipeline. + self._pipeline_start_event = asyncio.Event() + + # This event is used to indicate a finalize frame (e.g. EndFrame, + # StopFrame) has been received at the end of the pipeline. + self._pipeline_end_event = asyncio.Event() + + # When bridged, wrap the user pipeline with bus edge processors + # so frames tee onto the bus at the source/sink and incoming bus + # frames are injected back into the local pipeline. The edges + # read the worker's bus lazily, so the bus only needs to be set + # (via ``attach()``) before ``run()`` is called. + if bridged is not None: + edge_source = _BusEdgeProcessor( + worker=self, + direction=FrameDirection.UPSTREAM, + bridges=bridged, + exclude_frames=exclude_frames, + name=f"{self}::EdgeSource", + ) + edge_sink = _BusEdgeProcessor( + worker=self, + direction=FrameDirection.DOWNSTREAM, + bridges=bridged, + exclude_frames=exclude_frames, + name=f"{self}::EdgeSink", + ) + pipeline = Pipeline([edge_source, pipeline, edge_sink]) + + # This is the final pipeline. It is composed of a source processor, + # followed by the user pipeline, and ending with a sink processor. The + # source allows us to receive and react to upstream frames, and the sink + # allows us to receive and react to downstream frames. + source = PipelineSource(self._source_push_frame, name=f"{self}::Source") + self._sink = PipelineSink(self._sink_push_frame, name=f"{self}::Sink") + # Only prepend the RTVIProcessor if we created it ourselves. When the + # user already placed it inside their pipeline we must not insert it + # again or it will appear twice in the frame chain. + processors = [self._rtvi, pipeline] if prepend_rtvi else [pipeline] + self._pipeline = Pipeline(processors, source=source, sink=self._sink) + + # The worker observer acts as a proxy to the provided observers. This way, + # we only need to pass a single observer (using the StartFrame) which + # then just acts as a proxy. + self._observer = WorkerObserver(observers=observers) + + # These events can be used to check which frames make it to the source + # or sink processors. Instead of calling the event handlers for every + # frame the user needs to specify which events they are interested + # in. This is mainly for efficiency reason because each event handler + # creates a worker and most likely you only care about one or two frame + # types. + self._reached_upstream_types: set[type[Frame]] = set() + self._reached_downstream_types: set[type[Frame]] = set() + self._register_event_handler("on_frame_reached_upstream") + self._register_event_handler("on_frame_reached_downstream") + self._register_event_handler("on_idle_timeout") + self._register_event_handler("on_pipeline_started") + self._register_event_handler("on_pipeline_finished") + self._register_event_handler("on_pipeline_error") + + # Bridge pipeline lifecycle to the BaseWorker lifecycle so the bus + # registry sees this worker as ready/finished. + @self.event_handler("on_pipeline_started") + async def on_started(_task, _frame): + await self.start() + + @self.event_handler("on_pipeline_finished") + async def on_finished(_task, _frame): + await self.stop() + + @property + def params(self) -> PipelineParams: + """Get the pipeline parameters for this worker. + + Returns: + The pipeline parameters configuration. + """ + return self._params + + @property + def bridged(self) -> bool: + """Whether this pipeline is bridged onto the bus.""" + return self._bridged is not None + + @property + def app_resources(self) -> Any: + """Get the application-defined resources passed to this worker. + + This is the same object passed to the constructor as + ``app_resources``. Tool handlers can also access it via + ``FunctionCallParams.app_resources``. The framework returns the + original reference; mutations are visible to all callers. + + Returns: + The application-defined resources, or ``None`` if none were + passed. + """ + return self._app_resources + + @property + def pipeline(self) -> BasePipeline: + """Get the full pipeline managed by this pipeline worker. + + This will also include any internal processors added by the pipeline worker. + + Returns: + The pipeline managed by the pipeline worker. + """ + return self._pipeline + + @property + def turn_tracking_observer(self) -> TurnTrackingObserver | None: + """Get the turn tracking observer if enabled. + + Returns: + The turn tracking observer instance or None if not enabled. + """ + return self._turn_tracking_observer + + @property + def turn_trace_observer(self) -> TurnTraceObserver | None: + """Get the turn trace observer if enabled. + + Returns: + The turn trace observer instance or None if not enabled. + """ + return self._turn_trace_observer + + @property + def rtvi(self) -> RTVIProcessor: + """Get the RTVI processor if RTVI is enabled. + + Returns: + The RTVI processor added to the pipeline when RTVI is enabled. + """ + if not self._rtvi: + raise Exception(f"{self} RTVI is not enabled.") + return self._rtvi + + @property + def reached_upstream_types(self) -> tuple[type[Frame], ...]: + """Get the currently configured upstream frame type filters. + + Returns: + Tuple of frame types that trigger the on_frame_reached_upstream event. + """ + return tuple(self._reached_upstream_types) + + @property + def reached_downstream_types(self) -> tuple[type[Frame], ...]: + """Get the currently configured downstream frame type filters. + + Returns: + Tuple of frame types that trigger the on_frame_reached_downstream event. + """ + return tuple(self._reached_downstream_types) + + def add_observer(self, observer: BaseObserver): + """Add an observer to monitor pipeline execution. + + Args: + observer: The observer to add to the pipeline monitoring. + """ + self._observer.add_observer(observer) + + async def remove_observer(self, observer: BaseObserver): + """Remove an observer from pipeline monitoring. + + Args: + observer: The observer to remove from pipeline monitoring. + """ + await self._observer.remove_observer(observer) + + def set_reached_upstream_filter(self, types: tuple[type[Frame], ...]): + """Set which frame types trigger the on_frame_reached_upstream event. + + Args: + types: Tuple of frame types to monitor for upstream events. + """ + self._reached_upstream_types = set(types) + + def set_reached_downstream_filter(self, types: tuple[type[Frame], ...]): + """Set which frame types trigger the on_frame_reached_downstream event. + + Args: + types: Tuple of frame types to monitor for downstream events. + """ + self._reached_downstream_types = set(types) + + def add_reached_upstream_filter(self, types: tuple[type[Frame], ...]): + """Add frame types to trigger the on_frame_reached_upstream event. + + Args: + types: Tuple of frame types to add to upstream monitoring. + """ + self._reached_upstream_types.update(types) + + def add_reached_downstream_filter(self, types: tuple[type[Frame], ...]): + """Add frame types to trigger the on_frame_reached_downstream event. + + Args: + types: Tuple of frame types to add to downstream monitoring. + """ + self._reached_downstream_types.update(types) + + def has_finished(self) -> bool: + """Check if the pipeline worker has finished execution. + + This indicates whether the worker has finished, meaning all processors + have stopped. + + Returns: + True if all processors have stopped and the worker is complete. + """ + return self._finished + + async def stop_when_done(self): + """Schedule the pipeline to stop after processing all queued frames. + + Sends an EndFrame to gracefully terminate the pipeline once all + current processing is complete. + """ + logger.debug(f"Task {self} scheduled to stop when done") + await self.queue_frame(EndFrame()) + + async def cancel(self, *, reason: str | None = None): + """Request the running pipeline to cancel. + + Args: + reason: Optional reason to indicate why the pipeline is being cancelled. + """ + if not self._finished: + await self._cancel(reason=reason) + + async def run(self, params: PipelineWorkerParams): + """Start and manage the pipeline execution until completion or cancellation. + + Args: + params: Configuration parameters for pipeline execution. + """ + if self.has_finished(): + return + + # Setup processors. + await self._setup(params) + + # Create all main tasks and wait for the main push worker. This is the + # worker that pushes frames to the very beginning of our pipeline (i.e. to + # our controlled source processor). + await self._create_tasks() + + try: + # Wait for pipeline to finish. + await self._wait_for_pipeline_finished() + except asyncio.CancelledError: + logger.debug(f"Pipeline worker {self} got cancelled from outside...") + # We have been cancelled from outside, let's just cancel everything. + await self._cancel() + # Wait again for pipeline to finish. This time we have really + # cancelled, so it should really finish. + await self._wait_for_pipeline_finished() + # Re-raise in case there's more cleanup to do. + raise + finally: + # We can reach this point for different reasons: + # + # 1. The pipeline worker has finished (try case). + # 2. By an asyncio worker cancellation (except case). + logger.debug(f"Pipeline worker {self} is finishing...") + await self._cancel_tasks() + if self._check_dangling_tasks: + self._print_dangling_tasks() + self._finished = True + logger.debug(f"Pipeline worker {self} has finished") + + async def queue_frame( + self, frame: Frame, direction: FrameDirection = FrameDirection.DOWNSTREAM + ): + """Queue a single frame to be pushed through the pipeline. + + Downstream frames are pushed from the beginning of the pipeline. + Upstream frames are pushed from the end of the pipeline. + + Args: + frame: The frame to be processed. + direction: The direction to push the frame. Defaults to downstream. + """ + if direction == FrameDirection.DOWNSTREAM: + await self._push_queue.put(frame) + else: + await self._sink.queue_frame(frame, direction) + + async def queue_frames( + self, + frames: Iterable[Frame] | AsyncIterable[Frame], + direction: FrameDirection = FrameDirection.DOWNSTREAM, + ): + """Queue multiple frames to be pushed through the pipeline. + + Downstream frames are pushed from the beginning of the pipeline. + Upstream frames are pushed from the end of the pipeline. + + Args: + frames: An iterable or async iterable of frames to be processed. + direction: The direction to push the frames. Defaults to downstream. + """ + if isinstance(frames, AsyncIterable): + async for frame in frames: + await self.queue_frame(frame, direction) + elif isinstance(frames, Iterable): + for frame in frames: + await self.queue_frame(frame, direction) + + async def _cancel(self, *, reason: str | None = None): + """Internal cancellation logic for the pipeline worker. + + Args: + reason: Optional reason to indicate why the pipeline is being cancelled. + """ + if not self._cancelled: + logger.debug(f"Cancelling pipeline worker {self}") + self._cancelled = True + await self.queue_frame(CancelFrame(reason=reason)) + + async def _create_tasks(self): + """Create and start all pipeline processing tasks.""" + self._process_push_task = self.create_task(self._process_push_queue()) + return self._process_push_task + + def _maybe_start_heartbeat_tasks(self): + """Start heartbeat tasks if heartbeats are enabled and not already running.""" + if self._params.enable_heartbeats and self._heartbeat_push_task is None: + self._heartbeat_push_task = self.create_task(self._heartbeat_push_handler()) + self._heartbeat_monitor_task = self.create_task(self._heartbeat_monitor_handler()) + + def _maybe_start_idle_task(self): + """Start idle monitoring worker if idle timeout is configured.""" + if self._idle_timeout_secs: + self._idle_monitor_task = self.create_task(self._idle_monitor_handler()) + + async def _cancel_tasks(self): + """Cancel all running pipeline tasks.""" + if self._process_push_task: + await self.cancel_task(self._process_push_task) + self._process_push_task = None + + await self._maybe_cancel_heartbeat_tasks() + await self._maybe_cancel_idle_task() + + async def _maybe_cancel_heartbeat_tasks(self): + """Cancel heartbeat tasks if they are running.""" + if not self._params.enable_heartbeats: + return + + if self._heartbeat_push_task: + await self.cancel_task(self._heartbeat_push_task) + self._heartbeat_push_task = None + + if self._heartbeat_monitor_task: + await self.cancel_task(self._heartbeat_monitor_task) + self._heartbeat_monitor_task = None + + async def _maybe_cancel_idle_task(self): + """Cancel idle monitoring worker if it is running.""" + if self._idle_monitor_task: + await self.cancel_task(self._idle_monitor_task) + self._idle_monitor_task = None + + def _initial_metrics_frame(self) -> MetricsFrame: + """Create an initial metrics frame with zero values for all processors.""" + processors = self._pipeline.processors_with_metrics() + data = [] + for p in processors: + data.append(TTFBMetricsData(processor=p.name, value=0.0)) + data.append(ProcessingMetricsData(processor=p.name, value=0.0)) + return MetricsFrame(data=data) + + async def _wait_for_pipeline_start(self, frame: Frame): + """Wait for the specified start frame to reach the end of the pipeline.""" + logger.debug(f"{self}: Starting. Waiting for {frame} to reach the end of the pipeline...") + await self._pipeline_start_event.wait() + self._pipeline_start_event.clear() + logger.debug(f"{self}: {frame} reached the end of the pipeline, pipeline is now ready.") + + async def _wait_for_pipeline_end(self, frame: Frame): + """Wait for the specified frame to reach the end of the pipeline.""" + + async def wait_for_cancel(): + try: + await asyncio.wait_for( + self._pipeline_end_event.wait(), timeout=self._cancel_timeout_secs + ) + logger.debug(f"{self}: {frame} reached the end of the pipeline.") + except TimeoutError: + logger.warning( + f"{self}: timeout waiting for {frame} to reach the end of the pipeline (being blocked somewhere?)." + ) + finally: + await self._call_event_handler("on_pipeline_finished", frame) + + logger.debug(f"{self}: Closing. Waiting for {frame} to reach the end of the pipeline...") + + if isinstance(frame, CancelFrame): + await wait_for_cancel() + else: + await self._pipeline_end_event.wait() + logger.debug(f"{self}: {frame} reached the end of the pipeline, pipeline is closing.") + + self._pipeline_end_event.clear() + + # We are really done. Setting ``_finished_event`` makes + # ``BaseWorker.wait()`` resolve for callers awaiting this worker. + self._finished_event.set() + + async def _wait_for_pipeline_finished(self): + await self._finished_event.wait() + # Make sure we wait for the main worker to complete. + if self._process_push_task: + await self._process_push_task + self._process_push_task = None + + async def _setup(self, params: PipelineWorkerParams): + """Set up the pipeline worker and all processors.""" + await super().setup(self._pipeline_task_manager) + + if self._bus is not None: + await self._bus.subscribe(self) + + mgr_params = TaskManagerParams(loop=params.loop) + self.task_manager.setup(mgr_params) + + setup = FrameProcessorSetup( + clock=self._clock, + task_manager=self.task_manager, + observer=self._observer, + pipeline_worker=self, + # Populate the deprecated `tool_resources` field for backwards + # compatibility with custom FrameProcessor subclasses whose + # ``setup()`` overrides still read it. Reading the field emits a + # DeprecationWarning; new code should read + # ``setup.pipeline_worker.app_resources`` instead. + tool_resources=self._app_resources, + ) + await self._pipeline.setup(setup) + + # Do any additional pipeline worker setup externally. + await self._load_setup_files() + + # Start worker observer. + await self._observer.setup(self.task_manager) + await self._observer.start() + + async def _cleanup(self, cleanup_pipeline: bool): + """Clean up the pipeline worker and processors.""" + # Cleanup base object. + await self.cleanup() + + # Cleanup observers. + await self._observer.stop() + await self._observer.cleanup() + + # End conversation tracing if it's active - this will also close any active turn span + if self._enable_tracing and self._turn_trace_observer: + self._turn_trace_observer.end_conversation_tracing() + + # Cleanup pipeline processors. + if cleanup_pipeline: + await self._pipeline.cleanup() + + async def _handle_worker_end(self, message: BusEndWorkerMessage) -> None: + """End the pipeline after propagating end to children. + + Drives shutdown through the pipeline (``EndFrame``) so + ``_finished_event`` fires once the frame drains through the + sink, rather than calling ``stop()`` directly. + """ + logger.debug(f"Worker '{self}': received end") + await self._propagate_end_to_children(message) + await self.queue_frame(EndFrame(reason=message.reason)) + + async def _handle_worker_cancel(self, message: BusCancelWorkerMessage) -> None: + """Cancel the pipeline after propagating cancel to children. + + Drives shutdown through the pipeline (``CancelFrame``) so + ``_finished_event`` fires once the frame drains, rather than + calling ``stop()`` directly. + """ + logger.debug(f"Worker '{self}': received cancel") + await self._propagate_cancel_to_children(message) + await self.cancel(reason=message.reason) + + async def _process_push_queue(self): + """Process frames from the push queue and send them through the pipeline. + + This is the worker that runs the pipeline for the first time by sending + a StartFrame and by pushing any other frames queued by the user. It runs + until the worker is cancelled or stopped (e.g. with an EndFrame). + """ + self._clock.start() + + self._maybe_start_idle_task() + + start_frame = StartFrame( + audio_in_sample_rate=self._params.audio_in_sample_rate, + audio_out_sample_rate=self._params.audio_out_sample_rate, + enable_metrics=self._params.enable_metrics, + enable_tracing=self._enable_tracing, + enable_usage_metrics=self._params.enable_usage_metrics, + report_only_initial_ttfb=self._params.report_only_initial_ttfb, + tracing_context=self._tracing_context, + ) + start_frame.metadata = self._create_start_metadata() + await self._pipeline.queue_frame(start_frame) + + # Wait for the pipeline to be started before pushing any other frame. + await self._wait_for_pipeline_start(start_frame) + + if self._params.enable_metrics and self._params.send_initial_empty_metrics: + await self._pipeline.queue_frame(self._initial_metrics_frame()) + + running = True + cleanup_pipeline = True + while running: + frame = await self._push_queue.get() + await self._pipeline.queue_frame(frame) + if isinstance(frame, (CancelFrame, EndFrame, StopFrame)): + await self._wait_for_pipeline_end(frame) + running = not isinstance(frame, (CancelFrame, EndFrame, StopFrame)) + cleanup_pipeline = not isinstance(frame, StopFrame) + self._push_queue.task_done() + await self._cleanup(cleanup_pipeline) + + async def _source_push_frame(self, frame: Frame, direction: FrameDirection): + """Process frames coming upstream from the pipeline. + + This is the worker that processes frames coming upstream from the + pipeline. These frames might indicate, for example, that we want the + pipeline to be stopped (e.g. EndTaskFrame) in which case we would send + an EndFrame down the pipeline. + """ + if isinstance(frame, tuple(self._reached_upstream_types)): + await self._call_event_handler("on_frame_reached_upstream", frame) + + if isinstance(frame, EndTaskFrame): + # Tell the worker we should end nicely. + logger.debug(f"{self}: received end worker frame upstream {frame}") + await self.queue_frame(EndFrame(reason=frame.reason)) + elif isinstance(frame, CancelTaskFrame): + # Tell the worker we should end right away. + logger.debug(f"{self}: received cancel worker frame upstream {frame}") + await self.queue_frame(CancelFrame(reason=frame.reason)) + elif isinstance(frame, StopTaskFrame): + # Tell the worker we should stop nicely. + logger.debug(f"{self}: received stop worker frame upstream {frame}") + await self.queue_frame(StopFrame()) + elif isinstance(frame, InterruptionTaskFrame): + # Tell the worker we should interrupt the pipeline. Note that we are + # bypassing the push queue and directly queue into the + # pipeline. This is in case the push worker is blocked waiting for a + # pipeline-ending frame to finish traversing the pipeline. + logger.debug(f"{self}: received interruption worker frame upstream {frame}") + await self._pipeline.queue_frame(InterruptionFrame()) + elif isinstance(frame, ErrorFrame): + await self._call_event_handler("on_pipeline_error", frame) + if frame.fatal: + logger.error(f"A fatal error occurred: {frame}") + # Cancel all tasks downstream. + await self.queue_frame(CancelFrame()) + else: + logger.warning(f"{self}: Something went wrong: {frame}") + + async def _sink_push_frame(self, frame: Frame, direction: FrameDirection): + """Process frames coming downstream from the pipeline. + + This tasks process frames coming downstream from the pipeline. For + example, heartbeat frames or an EndFrame which would indicate all + processors have handled the EndFrame and therefore we can exit the worker + cleanly. + """ + if isinstance(frame, tuple(self._reached_downstream_types)): + await self._call_event_handler("on_frame_reached_downstream", frame) + + if isinstance(frame, StartFrame): + await self._call_event_handler("on_pipeline_started", frame) + await self._observer.on_pipeline_started() + + # Start heartbeat tasks now that StartFrame has been processed + # by all processors in the pipeline + self._maybe_start_heartbeat_tasks() + + self._pipeline_start_event.set() + elif isinstance(frame, EndFrame): + await self._call_event_handler("on_pipeline_finished", frame) + self._pipeline_end_event.set() + elif isinstance(frame, StopFrame): + await self._call_event_handler("on_pipeline_finished", frame) + self._pipeline_end_event.set() + elif isinstance(frame, CancelFrame): + self._pipeline_end_event.set() + elif isinstance(frame, HeartbeatFrame): + await self._heartbeat_queue.put(frame) + elif isinstance(frame, EndTaskFrame): + logger.debug(f"{self}: received end worker frame downstream {frame}") + await self.queue_frame(EndTaskFrame(reason=frame.reason), FrameDirection.UPSTREAM) + elif isinstance(frame, StopTaskFrame): + logger.debug(f"{self}: received stop worker frame downstream {frame}") + await self.queue_frame(StopTaskFrame(), FrameDirection.UPSTREAM) + elif isinstance(frame, CancelTaskFrame): + logger.debug(f"{self}: received cancel worker frame downstream {frame}") + await self.queue_frame(CancelTaskFrame(reason=frame.reason), FrameDirection.UPSTREAM) + elif isinstance(frame, InterruptionTaskFrame): + logger.debug(f"{self}: received interruption worker frame downstream {frame}") + await self.queue_frame(InterruptionTaskFrame(), FrameDirection.UPSTREAM) + + async def _heartbeat_push_handler(self): + """Push heartbeat frames at regular intervals.""" + while True: + # Don't use `queue_frame()` because if an EndFrame is queued the + # worker will just stop waiting for the pipeline to finish not + # allowing more frames to be pushed. + await self._pipeline.queue_frame(HeartbeatFrame(timestamp=self._clock.get_time())) + await asyncio.sleep(self._params.heartbeats_period_secs) + + async def _heartbeat_monitor_handler(self): + """Monitor heartbeat frames for processing time and timeout detection. + + This worker monitors heartbeat frames. If a heartbeat frame has not + been received for a long period a warning will be logged. It also logs + the time that a heartbeat frame takes to processes, that is how long it + takes for the heartbeat frame to traverse all the pipeline. + """ + wait_time = self._params.heartbeats_monitor_secs + while True: + try: + frame = await asyncio.wait_for(self._heartbeat_queue.get(), timeout=wait_time) + process_time = (self._clock.get_time() - frame.timestamp) / 1_000_000_000 + logger.trace(f"{self}: heartbeat frame processed in {process_time} seconds") + self._heartbeat_queue.task_done() + except TimeoutError: + logger.warning( + f"{self}: heartbeat frame not received for more than {wait_time} seconds" + ) + + async def _idle_monitor_handler(self): + """Monitor pipeline activity and detect idle conditions. + + Tracks frame activity and triggers idle timeout events when the + pipeline hasn't received relevant frames within the timeout period. + + Note: Heartbeats are excluded from idle detection. + """ + running = True + while running: + try: + await asyncio.wait_for(self._idle_event.wait(), timeout=self._idle_timeout_secs) + self._idle_event.clear() + except TimeoutError: + running = await self._idle_timeout_detected() + + async def _idle_timeout_detected(self) -> bool: + """Handle idle timeout detection and optional cancellation. + + Returns: + Whether the pipeline worker should continue running. + """ + # If we are cancelling, just exit the worker. + if self._cancelled: + return False + + logger.warning("Idle timeout detected.") + await self._call_event_handler("on_idle_timeout") + if self._cancel_on_idle_timeout: + logger.warning(f"Idle pipeline detected, cancelling pipeline worker...") + await self.cancel() + return False + return True + + async def _load_setup_files(self): + """Run ``setup_pipeline_worker`` from each file in ``PIPECAT_SETUP_FILES``. + + A setup file may define ``setup_pipeline_worker(worker)`` to attach event + handlers, observers, or other per-worker wiring. + """ + await run_setup_hook(target=self, function_name="setup_pipeline_worker") + + def _print_dangling_tasks(self): + """Log any dangling tasks that haven't been properly cleaned up.""" + tasks = [t.get_name() for t in self.task_manager.current_tasks()] + if tasks: + logger.warning(f"{self} dangling tasks detected: {tasks}") + + def _create_start_metadata(self) -> dict[str, Any]: + """Build and return start metadata including user-provided values.""" + start_metadata = {} + + # Update with user provided metadata. + start_metadata.update(self._params.start_metadata) + + return start_metadata + + def _find_processor(self, processor: FrameProcessor, processor_type: type[T]) -> T | None: + """Recursively find a processor of the given type in the pipeline.""" + if isinstance(processor, processor_type): + return processor + + for p in processor.processors: + found = self._find_processor(p, processor_type) + if found: + return found + return None + + +class PipelineTask(PipelineWorker): + """Deprecated alias for :class:`PipelineWorker`. + + .. deprecated:: 1.3.0 + Use :class:`PipelineWorker` instead. ``PipelineTask`` will be removed + in a future release. + """ + + def __init__(self, *args, **kwargs): + """Initialize the pipeline worker (deprecated).""" + warnings.warn( + "PipelineTask is deprecated, use PipelineWorker instead.", + DeprecationWarning, + stacklevel=2, + ) + super().__init__(*args, **kwargs) + + +@dataclass +class PipelineTaskParams(PipelineWorkerParams): + """Deprecated alias for :class:`PipelineWorkerParams`. + + .. deprecated:: 1.3.0 + Use :class:`PipelineWorkerParams` instead. ``PipelineTaskParams`` will + be removed in a future release. + """ + + def __post_init__(self): + """Warn on construction.""" + warnings.warn( + "PipelineTaskParams is deprecated, use PipelineWorkerParams instead.", + DeprecationWarning, + stacklevel=2, + ) diff --git a/src/pipecat/pipeline/task_observer.py b/src/pipecat/pipeline/worker_observer.py similarity index 90% rename from src/pipecat/pipeline/task_observer.py rename to src/pipecat/pipeline/worker_observer.py index 819de93ed..0ffc65f7c 100644 --- a/src/pipecat/pipeline/task_observer.py +++ b/src/pipecat/pipeline/worker_observer.py @@ -4,7 +4,7 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""Task observer for managing pipeline frame observers. +"""Worker observer for managing pipeline frame observers. This module provides a proxy observer system that manages multiple observers for pipeline frame events, ensuring that observer processing doesn't block @@ -28,12 +28,12 @@ class Proxy: Parameters: queue: Queue for frame data awaiting observer processing. - task: Asyncio task running the observer's frame processing loop. + worker: Asyncio worker running the observer's frame processing loop. observer: The actual observer instance being proxied. """ queue: asyncio.Queue - task: asyncio.Task + worker: asyncio.Task observer: BaseObserver @@ -43,18 +43,18 @@ class _PipelineStartedSignal: pass -class TaskObserver(BaseObserver): +class WorkerObserver(BaseObserver): """Proxy observer that manages multiple observers without blocking the pipeline. This is a pipeline frame observer that is meant to be used as a proxy to the user provided observers. That is, this is the observer that should be passed to the frame processors. Then, every time a frame is pushed this - observer will call all the observers registered to the pipeline task. + observer will call all the observers registered to the pipeline worker. This observer makes sure that passing frames to observers doesn't block the - pipeline by creating a queue and a task for each user observer. When a frame + pipeline by creating a queue and a worker for each user observer. When a frame is received, it will be put in a queue for efficiency and later processed by - each task. + each worker. """ def __init__( @@ -63,7 +63,7 @@ class TaskObserver(BaseObserver): observers: list[BaseObserver] | None = None, **kwargs, ): - """Initialize the TaskObserver. + """Initialize the WorkerObserver. Args: observers: List of observers to manage. Defaults to empty list. @@ -101,8 +101,8 @@ class TaskObserver(BaseObserver): proxy = self._proxies[observer] # Remove the proxy so it doesn't get called anymore. del self._proxies[observer] - # Cancel the proxy task right away. - await self.cancel_task(proxy.task) + # Cancel the proxy worker right away. + await self.cancel_task(proxy.worker) # Remove the observer from the list. if observer in self._observers: @@ -118,7 +118,7 @@ class TaskObserver(BaseObserver): return for proxy in self._proxies.values(): - await self.cancel_task(proxy.task) + await self.cancel_task(proxy.worker) async def cleanup(self): """Cleanup all proxy observers.""" @@ -153,10 +153,10 @@ class TaskObserver(BaseObserver): def _create_proxy(self, observer: BaseObserver) -> Proxy: """Create a proxy for a single observer.""" queue = asyncio.Queue() - task = self.create_task( + worker = self.create_task( self._proxy_task_handler(queue, observer), f"{observer}::_proxy_task_handler" ) - proxy = Proxy(queue=queue, task=task, observer=observer) + proxy = Proxy(queue=queue, worker=worker, observer=observer) return proxy def _create_proxies(self, observers: list[BaseObserver]) -> dict[BaseObserver, Proxy]: diff --git a/src/pipecat/pipeline/worker_ready_decorator.py b/src/pipecat/pipeline/worker_ready_decorator.py new file mode 100644 index 000000000..88f07b44f --- /dev/null +++ b/src/pipecat/pipeline/worker_ready_decorator.py @@ -0,0 +1,61 @@ +# +# Copyright (c) 2026, Daily +# +# SPDX-License-Identifier: BSD 2-Clause License +# + +"""Decorator for marking methods as worker-ready handlers.""" + +from collections.abc import Callable + + +def worker_ready(*, name: str): + """Mark a method as a handler for a specific worker becoming ready. + + Decorated methods are automatically collected by `BaseWorker` at + initialization. When the worker starts, it calls `watch_worker` for + each decorated handler. When the watched worker registers, the + decorated method is called with the ready data. + + Example:: + + @worker_ready(name="greeter") + async def on_greeter_ready(self, data: WorkerReadyData) -> None: + await self.activate_worker("greeter", args=...) + + Args: + name: The name of the worker to watch. + """ + + def decorator(fn): + fn.worker_ready_name = name + return fn + + return decorator + + +def _collect_worker_ready_handlers(obj) -> dict: + """Collect all ``@worker_ready`` decorated bound methods from an object. + + Returns a dict mapping worker name to the bound method. + + Raises: + ValueError: If two handlers watch the same worker name. + """ + seen: set[str] = set() + handlers: dict[str, Callable] = {} + for cls in type(obj).__mro__: + for attr_name, val in cls.__dict__.items(): + if attr_name in seen: + continue + seen.add(attr_name) + if callable(val) and hasattr(val, "worker_ready_name"): + worker_name = val.worker_ready_name + if worker_name in handlers: + existing = handlers[worker_name].__name__ + raise ValueError( + f"Duplicate @worker_ready handler for '{worker_name}': " + f"'{attr_name}' conflicts with '{existing}'" + ) + handlers[worker_name] = getattr(obj, attr_name) + return handlers diff --git a/src/pipecat/processors/aggregators/llm_response_universal.py b/src/pipecat/processors/aggregators/llm_response_universal.py index bc158042e..c0f771b8b 100644 --- a/src/pipecat/processors/aggregators/llm_response_universal.py +++ b/src/pipecat/processors/aggregators/llm_response_universal.py @@ -1374,8 +1374,8 @@ class LLMAssistantAggregator(LLMContextAggregator): # is added to the context. Also, run this in a separate task to make # sure we don't block the pipeline. if properties and properties.on_context_updated: - task_name = f"{frame.function_name}:{frame.tool_call_id}:on_context_updated" - task = self.create_task(properties.on_context_updated(), task_name) + worker_name = f"{frame.function_name}:{frame.tool_call_id}:on_context_updated" + task = self.create_task(properties.on_context_updated(), worker_name) self._context_updated_tasks.add(task) task.add_done_callback(self._context_updated_task_finished) diff --git a/src/pipecat/processors/frame_processor.py b/src/pipecat/processors/frame_processor.py index 06c8e46f9..b28e91045 100644 --- a/src/pipecat/processors/frame_processor.py +++ b/src/pipecat/processors/frame_processor.py @@ -50,7 +50,7 @@ from pipecat.utils.base_object import BaseObject from pipecat.utils.frame_queue import FrameQueue if TYPE_CHECKING: - from pipecat.pipeline.task import PipelineTask + from pipecat.pipeline.worker import PipelineWorker class FrameDirection(Enum): @@ -75,31 +75,31 @@ class FrameProcessorSetup: Parameters: clock: The clock instance for timing operations. task_manager: The task manager for handling async operations. - pipeline_task: The :class:`PipelineTask` running this pipeline. Stored - on each processor as ``self.pipeline_task`` so processors can - reach task-scoped state (e.g. ``self.pipeline_task.app_resources``). + pipeline_worker: The :class:`PipelineWorker` running this pipeline. Stored + on each processor as ``self.pipeline_worker`` so processors can + reach task-scoped state (e.g. ``self.pipeline_worker.app_resources``). observer: Optional observer for monitoring frame processing events. - tool_resources: Deprecated. :class:`PipelineTask` continues to populate + tool_resources: Deprecated. :class:`PipelineWorker` continues to populate this with ``app_resources`` so that custom :class:`FrameProcessor` subclasses whose ``setup()`` overrides read ``setup.tool_resources`` keep working. New code should read - ``setup.pipeline_task.app_resources`` instead. + ``setup.pipeline_worker.app_resources`` instead. .. deprecated:: 1.2.0 Reading this attribute emits a ``DeprecationWarning``. Read - ``setup.pipeline_task.app_resources`` instead. + ``setup.pipeline_worker.app_resources`` instead. ``tool_resources`` will be removed in a future version. """ clock: BaseClock task_manager: BaseTaskManager - pipeline_task: PipelineTask + pipeline_worker: PipelineWorker observer: BaseObserver | None = None tool_resources: Any = None def __getattribute__(self, name: str) -> Any: # Warn when user code reads the deprecated ``tool_resources`` field. - # Set is unaffected (goes through ``__setattr__``), so PipelineTask can + # Set is unaffected (goes through ``__setattr__``), so PipelineWorker can # populate it for backwards compat without tripping the warning. if name == "tool_resources": value = object.__getattribute__(self, "tool_resources") @@ -108,7 +108,7 @@ class FrameProcessorSetup: warnings.simplefilter("always") warnings.warn( "`FrameProcessorSetup.tool_resources` is deprecated since 1.2.0; " - "read `setup.pipeline_task.app_resources` instead.", + "read `setup.pipeline_worker.app_resources` instead.", DeprecationWarning, stacklevel=2, ) @@ -221,8 +221,8 @@ class FrameProcessor(BaseObject): self._observer: BaseObserver | None = None # Pipeline Task. Populated by ``setup()``; accessing the - # ``pipeline_task`` property before setup raises. - self._pipeline_task: PipelineTask | None = None # set in setup() + # ``pipeline_worker`` property before setup raises. + self._pipeline_worker: PipelineWorker | None = None # set in setup() # Other properties self._enable_metrics = False @@ -367,19 +367,33 @@ class FrameProcessor(BaseObject): return self._report_only_initial_ttfb @property - def pipeline_task(self) -> PipelineTask: - """Get the :class:`PipelineTask` this processor is running in. + def pipeline_worker(self) -> PipelineWorker: + """Get the :class:`PipelineWorker` this processor is running in. - Provides access to task-scoped state from inside a processor — most - notably ``self.pipeline_task.app_resources`` for the application's + Provides access to worker-scoped state from inside a processor — most + notably ``self.pipeline_worker.app_resources`` for the application's shared bag of resources (DB handles, clients, feature flags, etc.). Returns: - The :class:`PipelineTask` instance that set up this processor. + The :class:`PipelineWorker` instance that set up this processor. """ - if not self._pipeline_task: - raise Exception(f"{self} pipeline task is still not set.") - return self._pipeline_task + if not self._pipeline_worker: + raise Exception(f"{self} pipeline worker is still not set.") + return self._pipeline_worker + + @property + def pipeline_task(self) -> PipelineWorker: + """Deprecated alias for :attr:`pipeline_worker`. + + .. deprecated:: 1.3.0 + Use :attr:`pipeline_worker` instead. + """ + warnings.warn( + "FrameProcessor.pipeline_task is deprecated, use pipeline_worker instead.", + DeprecationWarning, + stacklevel=2, + ) + return self.pipeline_worker def processors_with_metrics(self): """Return processors that can generate metrics. @@ -503,7 +517,7 @@ class FrameProcessor(BaseObject): await super().setup(setup.task_manager) self._clock = setup.clock self._observer = setup.observer - self._pipeline_task = setup.pipeline_task + self._pipeline_worker = setup.pipeline_worker # Create processing tasks. self.__create_input_task() diff --git a/src/pipecat/registry/__init__.py b/src/pipecat/registry/__init__.py index 083513eab..2626c5349 100644 --- a/src/pipecat/registry/__init__.py +++ b/src/pipecat/registry/__init__.py @@ -4,10 +4,10 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""Task registry for tracking known tasks across runners.""" +"""Worker registry for tracking known workers across runners.""" -from pipecat.registry.registry import TaskRegistry +from pipecat.registry.registry import WorkerRegistry __all__ = [ - "TaskRegistry", + "WorkerRegistry", ] diff --git a/src/pipecat/registry/registry.py b/src/pipecat/registry/registry.py index dde4cb95b..bcf0c6093 100644 --- a/src/pipecat/registry/registry.py +++ b/src/pipecat/registry/registry.py @@ -4,40 +4,40 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""Shared registry for tracking known tasks across runners.""" +"""Shared registry for tracking known workers across runners.""" from collections import defaultdict from collections.abc import Callable, Coroutine from loguru import logger -from pipecat.registry.types import TaskReadyData +from pipecat.registry.types import WorkerReadyData -WatchHandler = Callable[[TaskReadyData], Coroutine] +WatchHandler = Callable[[WorkerReadyData], Coroutine] -class TaskRegistry: - """Tracks all known tasks across local and remote runners. +class WorkerRegistry: + """Tracks all known workers across local and remote runners. - Owned by a runner and shared with its tasks. Organizes tasks into + Owned by a runner and shared with its workers. Organizes workers into local (this runner) and remote (other runners) so they are easy to - distinguish. Deduplication is built in: each task name is + distinguish. Deduplication is built in: each worker name is registered at most once. Notifications use a targeted watch mechanism: call - ``watch(task_name, handler)`` to be notified when a specific task + ``watch(worker_name, handler)`` to be notified when a specific worker registers. """ def __init__(self, runner_name: str): - """Initialize the TaskRegistry. + """Initialize the WorkerRegistry. Args: runner_name: Name of the runner that owns this registry. """ self._runner_name = runner_name - self._local_tasks: dict[str, TaskReadyData] = {} - self._remote_tasks: dict[str, dict[str, TaskReadyData]] = defaultdict(dict) + self._local_workers: dict[str, WorkerReadyData] = {} + self._remote_workers: dict[str, dict[str, WorkerReadyData]] = defaultdict(dict) self._watches: dict[str, list[WatchHandler]] = defaultdict(list) @property @@ -46,84 +46,84 @@ class TaskRegistry: return self._runner_name @property - def local_tasks(self) -> list[str]: - """Names of tasks registered under this runner.""" - return list(self._local_tasks.keys()) + def local_workers(self) -> list[str]: + """Names of workers registered under this runner.""" + return list(self._local_workers.keys()) @property - def remote_tasks(self) -> list[str]: - """Names of tasks registered under remote runners.""" + def remote_workers(self) -> list[str]: + """Names of workers registered under remote runners.""" result: list[str] = [] - for tasks in self._remote_tasks.values(): - result.extend(tasks.keys()) + for workers in self._remote_workers.values(): + result.extend(workers.keys()) return result - def get(self, task_name: str) -> TaskReadyData | None: - """Look up a registered task by name. + def get(self, worker_name: str) -> WorkerReadyData | None: + """Look up a registered worker by name. Args: - task_name: The task name to look up. + worker_name: The worker name to look up. Returns: - The task's ``TaskReadyData``, or None if not found. + The worker's ``WorkerReadyData``, or None if not found. """ - if task_name in self._local_tasks: - return self._local_tasks[task_name] - for tasks in self._remote_tasks.values(): - if task_name in tasks: - return tasks[task_name] + if worker_name in self._local_workers: + return self._local_workers[worker_name] + for workers in self._remote_workers.values(): + if worker_name in workers: + return workers[worker_name] return None - def __contains__(self, task_name: str) -> bool: - return self.get(task_name) is not None + def __contains__(self, worker_name: str) -> bool: + return self.get(worker_name) is not None - async def watch(self, task_name: str, handler: WatchHandler) -> None: - """Watch for a specific task's registration. + async def watch(self, worker_name: str, handler: WatchHandler) -> None: + """Watch for a specific worker's registration. - If the task is already registered, the handler fires immediately. + If the worker is already registered, the handler fires immediately. Args: - task_name: The task name to watch for. - handler: Async callable invoked with the task's data. + worker_name: The worker name to watch for. + handler: Async callable invoked with the worker's data. """ - self._watches[task_name].append(handler) - existing = self.get(task_name) + self._watches[worker_name].append(handler) + existing = self.get(worker_name) if existing: await handler(existing) - async def register(self, task_data: TaskReadyData) -> bool: - """Register a task. Returns True if the task was new. + async def register(self, worker_data: WorkerReadyData) -> bool: + """Register a worker. Returns True if the worker was new. - If the task is already registered, this is a no-op and returns - False. Otherwise the task is added and watchers are notified. + If the worker is already registered, this is a no-op and returns + False. Otherwise the worker is added and watchers are notified. Args: - task_data: Information about the task to register. + worker_data: Information about the worker to register. Returns: - True if the task was newly registered, False if already known. + True if the worker was newly registered, False if already known. """ - is_local = task_data.runner == self._runner_name - target = self._local_tasks if is_local else self._remote_tasks[task_data.runner] + is_local = worker_data.runner == self._runner_name + target = self._local_workers if is_local else self._remote_workers[worker_data.runner] - if task_data.task_name in target: + if worker_data.worker_name in target: return False # Warn if the same name exists on a different runner - existing = self.get(task_data.task_name) - if existing and existing.runner != task_data.runner: + existing = self.get(worker_data.worker_name) + if existing and existing.runner != worker_data.runner: logger.warning( - f"Task '{task_data.task_name}' registered on both " - f"'{existing.runner}' and '{task_data.runner}'" + f"Worker '{worker_data.worker_name}' registered on both " + f"'{existing.runner}' and '{worker_data.runner}'" ) - target[task_data.task_name] = task_data - locality = "local" if is_local else task_data.runner - logger.debug(f"Task '{task_data.task_name}' ready ({locality})") - await self._notify(task_data) + target[worker_data.worker_name] = worker_data + locality = "local" if is_local else worker_data.runner + logger.debug(f"Worker '{worker_data.worker_name}' ready ({locality})") + await self._notify(worker_data) return True - async def _notify(self, task_data: TaskReadyData) -> None: + async def _notify(self, worker_data: WorkerReadyData) -> None: """Notify watchers of a new registration.""" - for handler in self._watches.get(task_data.task_name, []): - await handler(task_data) + for handler in self._watches.get(worker_data.worker_name, []): + await handler(worker_data) diff --git a/src/pipecat/registry/types.py b/src/pipecat/registry/types.py index 877cfb858..ac4b9d302 100644 --- a/src/pipecat/registry/types.py +++ b/src/pipecat/registry/types.py @@ -4,21 +4,21 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""Shared types for the task registry.""" +"""Shared types for the worker registry.""" from dataclasses import dataclass @dataclass -class TaskRegistryEntry: - """Information about a task in a registry snapshot. +class WorkerRegistryEntry: + """Information about a worker in a registry snapshot. Parameters: - name: The task's name. - parent: Name of the parent task, or None for root tasks. - active: Whether the task is currently active. - bridged: Whether the task is bridged. - started_at: Unix timestamp when the task became ready. + name: The worker's name. + parent: Name of the parent worker, or None for root tasks. + active: Whether the worker is currently active. + bridged: Whether the worker is bridged. + started_at: Unix timestamp when the worker became ready. """ name: str @@ -29,26 +29,26 @@ class TaskRegistryEntry: @dataclass -class TaskReadyData: - """Information about a registered task. +class WorkerReadyData: + """Information about a registered worker. Parameters: - task_name: The name of the task. - runner: The name of the runner managing this task. + worker_name: The name of the worker. + runner: The name of the runner managing this worker. """ - task_name: str + worker_name: str runner: str @dataclass -class TaskErrorData: - """Information about a task error. +class WorkerErrorData: + """Information about a worker error. Parameters: - task_name: The name of the task that errored. + worker_name: The name of the worker that errored. error: Description of the error. """ - task_name: str + worker_name: str error: str diff --git a/src/pipecat/services/llm_service.py b/src/pipecat/services/llm_service.py index 28070f33b..bea25878e 100644 --- a/src/pipecat/services/llm_service.py +++ b/src/pipecat/services/llm_service.py @@ -72,7 +72,7 @@ from pipecat.utils.context.llm_context_summarization import ( ) if TYPE_CHECKING: - from pipecat.pipeline.task import PipelineTask + from pipecat.pipeline.worker import PipelineWorker # Type alias for a callable that handles LLM function calls. @@ -117,7 +117,7 @@ class FunctionCallParams: it with ``properties=FunctionCallResultProperties(is_final=False)`` to push intermediate updates before the final result. app_resources: The application-defined resources passed to - ``PipelineTask(..., app_resources=...)``. Same object — passed by + ``PipelineWorker(..., app_resources=...)``. Same object — passed by reference, not a copy. Use it to share DB handles, clients, state, feature flags, etc. across all of a session's tool handlers. """ @@ -131,7 +131,7 @@ class FunctionCallParams: # treat it invariantly, rejecting `LLMService[XAdapter]` at the call # sites that build FunctionCallParams. llm: LLMService[Any] - pipeline_task: PipelineTask + pipeline_worker: PipelineWorker context: LLMContext result_callback: FunctionCallResultCallback app_resources: Any = None @@ -963,10 +963,10 @@ class LLMService(UserTurnCompletionLLMServiceMixin, AIService, Generic[TAdapter] tool_call_id=runner_item.tool_call_id, arguments=runner_item.arguments, llm=self, - pipeline_task=self.pipeline_task, + pipeline_worker=self.pipeline_worker, context=runner_item.context, result_callback=function_call_result_callback, - app_resources=self.pipeline_task.app_resources, + app_resources=self.pipeline_worker.app_resources, ), ) else: @@ -976,10 +976,10 @@ class LLMService(UserTurnCompletionLLMServiceMixin, AIService, Generic[TAdapter] tool_call_id=runner_item.tool_call_id, arguments=runner_item.arguments, llm=self, - pipeline_task=self.pipeline_task, + pipeline_worker=self.pipeline_worker, context=runner_item.context, result_callback=function_call_result_callback, - app_resources=self.pipeline_task.app_resources, + app_resources=self.pipeline_worker.app_resources, ) await item.handler(params) except Exception as e: diff --git a/src/pipecat/tasks/llm/__init__.py b/src/pipecat/tasks/llm/__init__.py deleted file mode 100644 index 6383557b5..000000000 --- a/src/pipecat/tasks/llm/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -# -# Copyright (c) 2026, Daily -# -# SPDX-License-Identifier: BSD 2-Clause License -# - -"""LLM task package -- `LLMTask`, `LLMContextTask`, and the `@tool` decorator.""" - -from pipecat.tasks.llm.llm_context_task import LLMContextTask -from pipecat.tasks.llm.llm_task import LLMTask, LLMTaskActivationArgs -from pipecat.tasks.llm.tool_decorator import tool - -__all__ = [ - "LLMTask", - "LLMTaskActivationArgs", - "LLMContextTask", - "tool", -] diff --git a/src/pipecat/tasks/proxy/websocket/__init__.py b/src/pipecat/tasks/proxy/websocket/__init__.py deleted file mode 100644 index 615e02293..000000000 --- a/src/pipecat/tasks/proxy/websocket/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -# -# Copyright (c) 2026, Daily -# -# SPDX-License-Identifier: BSD 2-Clause License -# - -"""WebSocket proxy tasks for forwarding bus messages.""" - -from pipecat.tasks.proxy.websocket.client import WebSocketProxyClientTask -from pipecat.tasks.proxy.websocket.server import WebSocketProxyServerTask - -__all__ = [ - "WebSocketProxyClientTask", - "WebSocketProxyServerTask", -] diff --git a/src/pipecat/tests/utils.py b/src/pipecat/tests/utils.py index 23df0ff81..cd0caa4a9 100644 --- a/src/pipecat/tests/utils.py +++ b/src/pipecat/tests/utils.py @@ -20,7 +20,7 @@ from pipecat.frames.frames import ( from pipecat.observers.base_observer import BaseObserver, FramePushed from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.frame_processor import FrameDirection, FrameProcessor @@ -177,7 +177,7 @@ async def run_test( pipeline = Pipeline([source, processor, sink]) - task = PipelineTask( + worker = PipelineWorker( pipeline, cancel_on_idle_timeout=False, enable_rtvi=enable_rtvi, @@ -192,13 +192,13 @@ async def run_test( if isinstance(frame, SleepFrame): await asyncio.sleep(frame.sleep) else: - await task.queue_frame(frame, frames_to_send_direction) + await worker.queue_frame(frame, frames_to_send_direction) if send_end_frame: - await task.queue_frame(EndFrame()) + await worker.queue_frame(EndFrame()) runner = PipelineRunner() - await asyncio.gather(runner.run(task), push_frames()) + await asyncio.gather(runner.run(worker), push_frames()) # # Down frames diff --git a/src/pipecat/utils/tracing/tracing_context.py b/src/pipecat/utils/tracing/tracing_context.py index 63f0b84ae..53316888a 100644 --- a/src/pipecat/utils/tracing/tracing_context.py +++ b/src/pipecat/utils/tracing/tracing_context.py @@ -7,7 +7,7 @@ """Pipeline-scoped tracing context for OpenTelemetry tracing in Pipecat. This module provides a per-pipeline tracing context that holds the current -conversation and turn span contexts. Each PipelineTask creates its own +conversation and turn span contexts. Each PipelineWorker creates its own TracingContext, ensuring concurrent pipelines do not interfere with each other. """ @@ -31,7 +31,7 @@ class TracingContext: """Pipeline-scoped tracing context. Holds the current conversation and turn span contexts for a single pipeline. - Created by PipelineTask, passed to TurnTraceObserver (writer) and services + Created by PipelineWorker, passed to TurnTraceObserver (writer) and services (readers) via StartFrame. """ diff --git a/src/pipecat/workers/llm/__init__.py b/src/pipecat/workers/llm/__init__.py new file mode 100644 index 000000000..47a8690cb --- /dev/null +++ b/src/pipecat/workers/llm/__init__.py @@ -0,0 +1,18 @@ +# +# Copyright (c) 2026, Daily +# +# SPDX-License-Identifier: BSD 2-Clause License +# + +"""LLM worker package -- `LLMWorker`, `LLMContextWorker`, and the `@tool` decorator.""" + +from pipecat.workers.llm.llm_context_worker import LLMContextWorker +from pipecat.workers.llm.llm_worker import LLMWorker, LLMWorkerActivationArgs +from pipecat.workers.llm.tool_decorator import tool + +__all__ = [ + "LLMWorker", + "LLMWorkerActivationArgs", + "LLMContextWorker", + "tool", +] diff --git a/src/pipecat/tasks/llm/llm_context_task.py b/src/pipecat/workers/llm/llm_context_worker.py similarity index 79% rename from src/pipecat/tasks/llm/llm_context_task.py rename to src/pipecat/workers/llm/llm_context_worker.py index 189fd0044..4bca476af 100644 --- a/src/pipecat/tasks/llm/llm_context_task.py +++ b/src/pipecat/workers/llm/llm_context_worker.py @@ -4,9 +4,9 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""LLM task with a built-in `LLMContext` and aggregator pair. +"""LLM worker with a built-in `LLMContext` and aggregator pair. -Provides the `LLMContextTask` class that extends `LLMTask` with a +Provides the `LLMContextWorker` class that extends `LLMWorker` with a self-contained conversation context, removing the need for subclasses to manually wire `LLMContextAggregatorPair`. """ @@ -23,13 +23,13 @@ from pipecat.processors.aggregators.llm_response_universal import ( LLMUserAggregatorParams, ) from pipecat.services.llm_service import LLMService -from pipecat.tasks.llm.llm_task import LLMTask +from pipecat.workers.llm.llm_worker import LLMWorker -class LLMContextTask(LLMTask): - """LLM task that owns an `LLMContext` and a context aggregator pair. +class LLMContextWorker(LLMWorker): + """LLM worker that owns an `LLMContext` and a context aggregator pair. - Useful for tasks that need to track their own conversation history, + Useful for workers that need to track their own conversation history, typically workers that run their own LLM pipeline outside of a shared transport pipeline. Subclasses do not need to instantiate the context or aggregators themselves; the pipeline is built as @@ -37,12 +37,12 @@ class LLMContextTask(LLMTask): Example:: - task = LLMContextTask( + worker = LLMContextWorker( "worker", llm=OpenAILLMService(...), ) - @task.assistant_aggregator.event_handler("on_assistant_turn_stopped") + @worker.assistant_aggregator.event_handler("on_assistant_turn_stopped") async def _on_stopped(aggregator, message): ... """ @@ -59,15 +59,15 @@ class LLMContextTask(LLMTask): user_params: LLMUserAggregatorParams | None = None, assistant_params: LLMAssistantAggregatorParams | None = None, ): - """Initialize the LLMContextTask. + """Initialize the LLMContextWorker. Args: - name: Unique name for this task. + name: Unique name for this worker. llm: The LLM service. - active: Whether the task starts active. Defaults to False. - bridged: Bridge configuration forwarded to ``PipelineTask``. + active: Whether the worker starts active. Defaults to False. + bridged: Bridge configuration forwarded to ``PipelineWorker``. Pass ``()`` to wrap the pipeline with bus edges so it - can exchange frames with another bridged task. + can exchange frames with another bridged worker. defer_tool_frames: Whether to defer frames queued during tool execution until all tools complete. Defaults to True. context: Optional pre-built `LLMContext`. When omitted, a @@ -102,7 +102,7 @@ class LLMContextTask(LLMTask): @property def context(self) -> LLMContext: - """The `LLMContext` owned by this task.""" + """The `LLMContext` owned by this worker.""" return self._context @property diff --git a/src/pipecat/tasks/llm/llm_task.py b/src/pipecat/workers/llm/llm_worker.py similarity index 85% rename from src/pipecat/tasks/llm/llm_task.py rename to src/pipecat/workers/llm/llm_worker.py index 7471fbee1..3ff6cc23b 100644 --- a/src/pipecat/tasks/llm/llm_task.py +++ b/src/pipecat/workers/llm/llm_worker.py @@ -4,9 +4,9 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""LLM task with tool registration. +"""LLM worker with tool registration. -Provides the `LLMTask` class that extends `PipelineTask` with an LLM +Provides the `LLMWorker` class that extends `PipelineWorker` with an LLM pipeline and automatic tool registration. """ @@ -26,12 +26,12 @@ from pipecat.frames.frames import ( LLMSetToolsFrame, UninterruptibleFrame, ) -from pipecat.pipeline.base_task import TaskActivationArgs +from pipecat.pipeline.base_worker import WorkerActivationArgs from pipecat.pipeline.pipeline import Pipeline -from pipecat.pipeline.task import PipelineParams, PipelineTask +from pipecat.pipeline.worker import PipelineParams, PipelineWorker from pipecat.processors.frame_processor import FrameDirection from pipecat.services.llm_service import LLMService -from pipecat.tasks.llm.tool_decorator import _collect_tools +from pipecat.workers.llm.tool_decorator import _collect_tools FunctionCallResultCallback = Callable[..., Any] @@ -44,8 +44,8 @@ class PipelineFlushFrame(ControlFrame, UninterruptibleFrame): @dataclass -class LLMTaskActivationArgs(TaskActivationArgs): - """Activation arguments for LLM tasks. +class LLMWorkerActivationArgs(WorkerActivationArgs): + """Activation arguments for LLM workers. Attributes: messages: LLM context messages to inject on activation. @@ -57,8 +57,8 @@ class LLMTaskActivationArgs(TaskActivationArgs): run_llm: bool | None = None -class LLMTask(PipelineTask): - """Task with an LLM pipeline and automatic tool registration. +class LLMWorker(PipelineWorker): + """Worker with an LLM pipeline and automatic tool registration. Methods decorated with ``@tool`` are registered as direct functions on the LLM and tracked so that frames queued during tool execution @@ -66,12 +66,12 @@ class LLMTask(PipelineTask): Example:: - class MyTask(LLMTask): + class MyTask(LLMWorker): @tool async def my_function(self, params, arg: str): ... - task = MyTask("worker", bus=bus, llm=OpenAILLMService(api_key="...")) + worker = MyTask("worker", bus=bus, llm=OpenAILLMService(api_key="...")) """ def __init__( @@ -84,21 +84,21 @@ class LLMTask(PipelineTask): bridged: tuple[str, ...] | None = None, defer_tool_frames: bool = True, ): - """Initialize the LLMTask. + """Initialize the LLMWorker. Args: - name: Unique name for this task. + name: Unique name for this worker. llm: The LLM service. ``@tool`` decorated methods are automatically registered on it. pipeline: Optional pipeline override. When ``None``, defaults to ``Pipeline([llm])``. Subclasses can pass a custom pipeline that wraps the LLM with additional processors. - active: Whether the task starts active. Defaults to False. - bridged: Bridge configuration forwarded to ``PipelineTask``. + active: Whether the worker starts active. Defaults to False. + bridged: Bridge configuration forwarded to ``PipelineWorker``. Pass ``()`` to wrap the LLM pipeline with bus edge processors so it can exchange frames with another - bridged task. + bridged worker. defer_tool_frames: Whether to defer frames queued during tool execution until all tools complete. Defaults to True. """ @@ -127,7 +127,7 @@ class LLMTask(PipelineTask): enable_usage_metrics=True, ), ) - # PipelineTask's __init__ doesn't accept active; configure after. + # PipelineWorker's __init__ doesn't accept active; configure after. self._active = active self._pending_activation = active @@ -138,18 +138,18 @@ class LLMTask(PipelineTask): self.add_reached_downstream_filter((PipelineFlushFrame,)) @self.event_handler("on_frame_reached_upstream") - async def _on_flush_upstream(task, frame): + async def _on_flush_upstream(worker, frame): if isinstance(frame, PipelineFlushFrame): await super().queue_frame(PipelineFlushFrame()) @self.event_handler("on_frame_reached_downstream") - async def _on_flush_downstream(task, frame): + async def _on_flush_downstream(worker, frame): if isinstance(frame, PipelineFlushFrame): self._flush_done.set() @property def llm(self) -> LLMService: - """The LLM service this task wraps.""" + """The LLM service this worker wraps.""" return self._llm @property @@ -165,7 +165,7 @@ class LLMTask(PipelineTask): """ await super().on_activated(args) - activation = LLMTaskActivationArgs.from_dict(args) if args else LLMTaskActivationArgs() + activation = LLMWorkerActivationArgs.from_dict(args) if args else LLMWorkerActivationArgs() tools = self.build_tools() if tools: @@ -197,7 +197,7 @@ class LLMTask(PipelineTask): await super().queue_frame(frame, direction) def build_tools(self) -> list: - """Return the tools for this task's LLM. + """Return the tools for this worker's LLM. By default, returns all methods decorated with ``@tool``. Override to provide additional or different tools. @@ -231,26 +231,26 @@ class LLMTask(PipelineTask): await self._finish_function_call(result_callback, messages=messages) await super().end(reason=reason) - async def activate_task( + async def activate_worker( self, - task_name: str, + worker_name: str, *, - args: TaskActivationArgs | None = None, + args: WorkerActivationArgs | None = None, deactivate_self: bool = False, messages: list | None = None, result_callback: FunctionCallResultCallback | None = None, ) -> None: - """Activate another task, optionally finishing an in-progress tool call. + """Activate another worker, optionally finishing an in-progress tool call. When called from a ``@tool`` handler, pass ``params.result_callback`` to ensure any pending LLM output is fully delivered before the target is activated. Args: - task_name: The name of the task to activate. - args: Optional ``TaskActivationArgs`` forwarded to the target - task's ``on_activated`` handler. - deactivate_self: Whether to deactivate this task before activating + worker_name: The name of the worker to activate. + args: Optional ``WorkerActivationArgs`` forwarded to the target + worker's ``on_activated`` handler. + deactivate_self: Whether to deactivate this worker before activating the target. messages: Optional LLM messages to inject and speak before activating the target. The LLM runs immediately so the output @@ -258,7 +258,7 @@ class LLMTask(PipelineTask): result_callback: The ``result_callback`` from `FunctionCallParams`. """ await self._finish_function_call(result_callback, messages=messages) - await super().activate_task(task_name, args=args, deactivate_self=deactivate_self) + await super().activate_worker(worker_name, args=args, deactivate_self=deactivate_self) async def process_deferred_tool_frames( self, frames: list[tuple[Frame, FrameDirection]] @@ -311,7 +311,7 @@ class LLMTask(PipelineTask): async def _flush_pipeline(self) -> None: self._flush_done.clear() - # Bypass our deferral override by going to PipelineTask directly. + # Bypass our deferral override by going to PipelineWorker directly. await super().queue_frame(PipelineFlushFrame(), FrameDirection.UPSTREAM) await self._flush_done.wait() diff --git a/src/pipecat/tasks/llm/tool_decorator.py b/src/pipecat/workers/llm/tool_decorator.py similarity index 94% rename from src/pipecat/tasks/llm/tool_decorator.py rename to src/pipecat/workers/llm/tool_decorator.py index 69f9827fe..646fd27a2 100644 --- a/src/pipecat/tasks/llm/tool_decorator.py +++ b/src/pipecat/workers/llm/tool_decorator.py @@ -10,7 +10,7 @@ def tool(fn=None, *, cancel_on_interruption=True, timeout=None): """Mark a method as a tool. - On ``LLMTask`` subclasses, decorated methods are automatically + On ``LLMWorker`` subclasses, decorated methods are automatically registered with the LLM via ``register_direct_function`` and included in ``build_tools()``. @@ -28,7 +28,7 @@ def tool(fn=None, *, cancel_on_interruption=True, timeout=None): fn: The function to decorate (when used without arguments). cancel_on_interruption: Whether to cancel this tool call when an interruption occurs. Defaults to True. Only applies to - ``LLMTask`` tools. + ``LLMWorker`` tools. timeout: Optional timeout in seconds for this tool call. Defaults to None (uses the LLM service default). """ diff --git a/src/pipecat/tasks/proxy/__init__.py b/src/pipecat/workers/proxy/__init__.py similarity index 65% rename from src/pipecat/tasks/proxy/__init__.py rename to src/pipecat/workers/proxy/__init__.py index 834dd4293..608bd2711 100644 --- a/src/pipecat/tasks/proxy/__init__.py +++ b/src/pipecat/workers/proxy/__init__.py @@ -4,9 +4,9 @@ # SPDX-License-Identifier: BSD 2-Clause License # -"""Proxy tasks for forwarding bus messages over network transports.""" +"""Proxy workers for forwarding bus messages over network transports.""" -from pipecat.tasks.proxy.websocket import ( +from pipecat.workers.proxy.websocket import ( WebSocketProxyClientTask, WebSocketProxyServerTask, ) diff --git a/src/pipecat/workers/proxy/websocket/__init__.py b/src/pipecat/workers/proxy/websocket/__init__.py new file mode 100644 index 000000000..01bf26052 --- /dev/null +++ b/src/pipecat/workers/proxy/websocket/__init__.py @@ -0,0 +1,15 @@ +# +# Copyright (c) 2026, Daily +# +# SPDX-License-Identifier: BSD 2-Clause License +# + +"""WebSocket proxy workers for forwarding bus messages.""" + +from pipecat.workers.proxy.websocket.client import WebSocketProxyClientTask +from pipecat.workers.proxy.websocket.server import WebSocketProxyServerTask + +__all__ = [ + "WebSocketProxyClientTask", + "WebSocketProxyServerTask", +] diff --git a/src/pipecat/tasks/proxy/websocket/client.py b/src/pipecat/workers/proxy/websocket/client.py similarity index 68% rename from src/pipecat/tasks/proxy/websocket/client.py rename to src/pipecat/workers/proxy/websocket/client.py index bf63dd9d3..77f9864ab 100644 --- a/src/pipecat/tasks/proxy/websocket/client.py +++ b/src/pipecat/workers/proxy/websocket/client.py @@ -10,11 +10,11 @@ import asyncio from loguru import logger -from pipecat.bus import BusMessage, BusTaskRegistryMessage +from pipecat.bus import BusMessage, BusWorkerRegistryMessage from pipecat.bus.messages import BusLocalMessage from pipecat.bus.serializers import JSONMessageSerializer from pipecat.bus.serializers.base import MessageSerializer -from pipecat.pipeline.base_task import BaseTask +from pipecat.pipeline.base_worker import BaseWorker try: import websockets @@ -27,12 +27,12 @@ except ModuleNotFoundError as e: raise Exception(f"Missing module: {e}") -class WebSocketProxyClientTask(BaseTask): - """Forwards bus messages to a remote task over WebSocket. +class WebSocketProxyClientTask(BaseWorker): + """Forwards bus messages to a remote worker over WebSocket. Connects to a WebSocket URL and forwards messages between a local - task and a remote task. Only messages targeted at the remote task - are sent. Only messages targeted at the local task are accepted. + worker and a remote worker. Only messages targeted at the remote worker + are sent. Only messages targeted at the local worker are accepted. Event handlers available: @@ -44,19 +44,19 @@ class WebSocketProxyClientTask(BaseTask): proxy = WebSocketProxyClientTask( "proxy", url="ws://remote-server:8765/ws", - remote_task_name="worker", - local_task_name="voice", + remote_worker_name="worker", + local_worker_name="voice", ) @proxy.event_handler("on_connected") - async def on_connected(task, websocket): + async def on_connected(worker, websocket): logger.info("Connected to remote server") @proxy.event_handler("on_disconnected") - async def on_disconnected(task, websocket): + async def on_disconnected(worker, websocket): logger.info("Disconnected from remote server") - await runner.spawn(proxy) + await runner.add_worker(proxy) """ def __init__( @@ -64,8 +64,8 @@ class WebSocketProxyClientTask(BaseTask): name: str, *, url: str, - remote_task_name: str, - local_task_name: str, + remote_worker_name: str, + local_worker_name: str, forward_messages: tuple[type[BusMessage], ...] = (), headers: dict[str, str] | None = None, serializer: MessageSerializer | None = None, @@ -74,31 +74,31 @@ class WebSocketProxyClientTask(BaseTask): """Initialize the WebSocketProxyClientTask. Args: - name: Unique name for this task. + name: Unique name for this worker. url: The WebSocket URL to connect to. - remote_task_name: Name of the task on the remote server. - Only messages targeted at this task are forwarded. - local_task_name: Name of the local task that should + remote_worker_name: Name of the worker on the remote server. + Only messages targeted at this worker are forwarded. + local_worker_name: Name of the local worker that should receive responses. Only inbound messages targeted at - this task are accepted. + this worker are accepted. forward_messages: Additional message types to forward from - the local task (e.g. ``(BusFrameMessage,)`` for frame - routing). These are forwarded based on source task name + the local worker (e.g. ``(BusFrameMessage,)`` for frame + routing). These are forwarded based on source worker name only, regardless of target. headers: Optional HTTP headers sent with the WebSocket handshake (e.g. for authentication). serializer: Serializer for bus messages. Defaults to `JSONMessageSerializer`. - active: Whether the task starts active. Defaults to ``False`` + active: Whether the worker starts active. Defaults to ``False`` because ``on_activated`` opens the WebSocket connection, which is almost always a deliberate action triggered by an upstream event (e.g. the local client connecting). Pass - ``True`` to connect as soon as the task starts. + ``True`` to connect as soon as the worker starts. """ super().__init__(name, active=active) self._url = url - self._remote_task_name = remote_task_name - self._local_task_name = local_task_name + self._remote_worker_name = remote_worker_name + self._local_worker_name = local_worker_name self._forward_messages = forward_messages self._headers = headers or {} self._serializer = serializer or JSONMessageSerializer() @@ -112,17 +112,17 @@ class WebSocketProxyClientTask(BaseTask): """Connect to the remote WebSocket server.""" await super().on_activated(args) - logger.debug(f"Task '{self}': connecting to {self._url}") + logger.debug(f"Worker '{self}': connecting to {self._url}") self._ws = await connect(self._url, additional_headers=self._headers) - logger.debug(f"Task '{self}': connected to {self._url}") + logger.debug(f"Worker '{self}': connected to {self._url}") await self._call_event_handler("on_connected", self._ws) self._receive_task = self.create_task(self._receive_loop()) - # Schedule task right away. + # Schedule worker right away. await asyncio.sleep(0) async def stop(self) -> None: @@ -132,12 +132,12 @@ class WebSocketProxyClientTask(BaseTask): self._receive_task = None if self._ws: await self._ws.close() - logger.debug(f"Task '{self}': WebSocket connection closed") + logger.debug(f"Worker '{self}': WebSocket connection closed") self._ws = None await super().stop() async def on_bus_message(self, message: BusMessage) -> None: - """Forward messages targeted at the remote task. + """Forward messages targeted at the remote worker. Args: message: The bus message to process. @@ -150,12 +150,12 @@ class WebSocketProxyClientTask(BaseTask): if isinstance(message, BusLocalMessage): return - # Forward targeted messages to the remote task. - if message.target == self._remote_task_name: + # Forward targeted messages to the remote worker. + if message.target == self._remote_worker_name: await self._send_ws(message) - # Forward additional message types from the local task. + # Forward additional message types from the local worker. elif isinstance(message, self._forward_messages): - if message.source == self._local_task_name: + if message.source == self._local_worker_name: await self._send_ws(message) async def _send_ws(self, message: BusMessage) -> None: @@ -165,9 +165,9 @@ class WebSocketProxyClientTask(BaseTask): try: data = self._serializer.serialize(message) await self._ws.send(data) - logger.trace(f"Task '{self}': sent {message}") + logger.trace(f"Worker '{self}': sent {message}") except websockets.exceptions.ConnectionClosed: - logger.warning(f"Task '{self}': connection closed, stopping forwarding") + logger.warning(f"Worker '{self}': connection closed, stopping forwarding") ws = self._ws self._ws = None await self._call_event_handler("on_disconnected", ws) @@ -183,34 +183,34 @@ class WebSocketProxyClientTask(BaseTask): if not message: continue - # Accept registry messages (target=None) for task discovery. - if isinstance(message, BusTaskRegistryMessage): + # Accept registry messages (target=None) for worker discovery. + if isinstance(message, BusWorkerRegistryMessage): logger.trace( - f"Task '{self}': received registry from remote: {message.tasks}" + f"Worker '{self}': received registry from remote: {message.workers}" ) await self.send_bus_message(message) continue # Accept additional message types (e.g. BusFrameMessage). if self._forward_messages and isinstance(message, self._forward_messages): - logger.trace(f"Task '{self}': received {message} from remote") + logger.trace(f"Worker '{self}': received {message} from remote") await self.send_bus_message(message) continue - # Only accept other messages targeted at the local task. - if message.target != self._local_task_name: + # Only accept other messages targeted at the local worker. + if message.target != self._local_worker_name: logger.warning( - f"Task '{self}': dropped inbound message with " + f"Worker '{self}': dropped inbound message with " f"unexpected target '{message.target}'" ) continue - logger.trace(f"Task '{self}': received {message} from remote") + logger.trace(f"Worker '{self}': received {message} from remote") await self.send_bus_message(message) except Exception: - logger.exception(f"Task '{self}': failed to deserialize remote message") + logger.exception(f"Worker '{self}': failed to deserialize remote message") except websockets.exceptions.ConnectionClosed: - logger.warning(f"Task '{self}': WebSocket connection closed") + logger.warning(f"Worker '{self}': WebSocket connection closed") ws = self._ws self._ws = None await self._call_event_handler("on_disconnected", ws) diff --git a/src/pipecat/tasks/proxy/websocket/server.py b/src/pipecat/workers/proxy/websocket/server.py similarity index 63% rename from src/pipecat/tasks/proxy/websocket/server.py rename to src/pipecat/workers/proxy/websocket/server.py index 3708aa03c..e31e62ef6 100644 --- a/src/pipecat/tasks/proxy/websocket/server.py +++ b/src/pipecat/workers/proxy/websocket/server.py @@ -10,12 +10,12 @@ import asyncio from loguru import logger -from pipecat.bus import BusMessage, BusTaskRegistryMessage +from pipecat.bus import BusMessage, BusWorkerRegistryMessage from pipecat.bus.messages import BusLocalMessage from pipecat.bus.serializers import JSONMessageSerializer from pipecat.bus.serializers.base import MessageSerializer -from pipecat.pipeline.base_task import BaseTask -from pipecat.registry.types import TaskReadyData, TaskRegistryEntry +from pipecat.pipeline.base_worker import BaseWorker +from pipecat.registry.types import WorkerReadyData, WorkerRegistryEntry try: from starlette.websockets import WebSocket, WebSocketDisconnect, WebSocketState @@ -25,13 +25,13 @@ except ModuleNotFoundError as e: raise Exception(f"Missing module: {e}") -class WebSocketProxyServerTask(BaseTask): +class WebSocketProxyServerTask(BaseWorker): """Receives bus messages from a remote client over WebSocket. Accepts a FastAPI/Starlette WebSocket connection and forwards - messages between the remote client and a local task. Only messages - from the local task targeted at the remote task are sent. Only - inbound messages targeted at the local task are accepted. + messages between the remote client and a local worker. Only messages + from the local worker targeted at the remote worker are sent. Only + inbound messages targeted at the local worker are accepted. Event handlers available: @@ -46,19 +46,19 @@ class WebSocketProxyServerTask(BaseTask): proxy = WebSocketProxyServerTask( "gateway", websocket=websocket, - task_name="worker", - remote_task_name="voice", + worker_name="worker", + remote_worker_name="voice", ) @proxy.event_handler("on_client_connected") - async def on_client_connected(task, websocket): + async def on_client_connected(worker, websocket): logger.info("Client connected") @proxy.event_handler("on_client_disconnected") - async def on_client_disconnected(task, websocket): + async def on_client_disconnected(worker, websocket): logger.info("Client disconnected") - await runner.spawn(proxy) + await runner.add_worker(proxy) """ def __init__( @@ -66,32 +66,32 @@ class WebSocketProxyServerTask(BaseTask): name: str, *, websocket: WebSocket, - task_name: str, - remote_task_name: str, + worker_name: str, + remote_worker_name: str, forward_messages: tuple[type[BusMessage], ...] = (), serializer: MessageSerializer | None = None, ): """Initialize the WebSocketProxyServerTask. Args: - name: Unique name for this task. + name: Unique name for this worker. websocket: An accepted FastAPI/Starlette WebSocket connection. - task_name: Name of the local task to route messages to/from. - Only messages from this task are forwarded to the client. - remote_task_name: Name of the task on the remote client. - Only outbound messages targeted at this task are sent. - Only inbound messages targeted at the local task are accepted. + worker_name: Name of the local worker to route messages to/from. + Only messages from this worker are forwarded to the client. + remote_worker_name: Name of the worker on the remote client. + Only outbound messages targeted at this worker are sent. + Only inbound messages targeted at the local worker are accepted. forward_messages: Additional message types to forward from - the local task (e.g. ``(BusFrameMessage,)`` for frame - routing). These are forwarded based on source task name + the local worker (e.g. ``(BusFrameMessage,)`` for frame + routing). These are forwarded based on source worker name only, regardless of target. serializer: Serializer for bus messages. Defaults to `JSONMessageSerializer`. """ super().__init__(name) self._ws: WebSocket | None = websocket - self._task_name = task_name - self._remote_task_name = remote_task_name + self._worker_name = worker_name + self._remote_worker_name = remote_worker_name self._forward_messages = forward_messages self._serializer = serializer or JSONMessageSerializer() self._receive_task: asyncio.Task | None = None @@ -100,20 +100,20 @@ class WebSocketProxyServerTask(BaseTask): self._register_event_handler("on_client_disconnected") async def start(self) -> None: - """Start the WebSocket receive loop and watch the local task.""" + """Start the WebSocket receive loop and watch the local worker.""" await super().start() - logger.debug(f"Task '{self}': WebSocket proxy server ready") + logger.debug(f"Worker '{self}': WebSocket proxy server ready") await self._call_event_handler("on_client_connected", self._ws) self._receive_task = self.create_task(self._receive_loop()) - # Schedule task right away. + # Schedule worker right away. await asyncio.sleep(0) - # Watch the local task so we can notify the remote side when it's ready. - await self.watch_task(self._task_name) + # Watch the local worker so we can notify the remote side when it's ready. + await self.watch_worker(self._worker_name) async def stop(self) -> None: """Cancel the receive loop and close the WebSocket connection.""" @@ -122,31 +122,31 @@ class WebSocketProxyServerTask(BaseTask): self._receive_task = None if self._ws and self._ws.client_state == WebSocketState.CONNECTED: await self._ws.close() - logger.debug(f"Task '{self}': WebSocket connection closed") + logger.debug(f"Worker '{self}': WebSocket connection closed") await super().stop() - async def on_task_ready(self, data: TaskReadyData) -> None: - """Notify the remote client that the local task is ready.""" + async def on_worker_ready(self, data: WorkerReadyData) -> None: + """Notify the remote client that the local worker is ready.""" if not self._ws: return - if data.task_name != self._task_name: + if data.worker_name != self._worker_name: return - logger.debug(f"Task '{self}': local task '{self._task_name}' ready, notifying remote") + logger.debug(f"Worker '{self}': local worker '{self._worker_name}' ready, notifying remote") try: - msg = BusTaskRegistryMessage( + msg = BusWorkerRegistryMessage( source=self.name, runner=data.runner, - tasks=[TaskRegistryEntry(name=self._task_name)], + workers=[WorkerRegistryEntry(name=self._worker_name)], ) await self._send_ws(msg) except Exception: - logger.exception(f"Task '{self}': failed to send registry to remote") + logger.exception(f"Worker '{self}': failed to send registry to remote") async def on_bus_message(self, message: BusMessage) -> None: - """Forward messages from the local task to the remote client. + """Forward messages from the local worker to the remote client. Args: message: The bus message to process. @@ -159,13 +159,13 @@ class WebSocketProxyServerTask(BaseTask): if isinstance(message, BusLocalMessage): return - if message.source != self._task_name: + if message.source != self._worker_name: return - # Forward targeted messages from the local task to the remote task. - if message.target == self._remote_task_name: + # Forward targeted messages from the local worker to the remote worker. + if message.target == self._remote_worker_name: await self._send_ws(message) - # Forward additional message types from the local task. + # Forward additional message types from the local worker. elif isinstance(message, self._forward_messages): await self._send_ws(message) @@ -176,9 +176,9 @@ class WebSocketProxyServerTask(BaseTask): try: data = self._serializer.serialize(message) await self._ws.send_bytes(data) - logger.trace(f"Task '{self}': sent {message}") + logger.trace(f"Worker '{self}': sent {message}") except WebSocketDisconnect: - logger.warning(f"Task '{self}': connection closed, stopping forwarding") + logger.warning(f"Worker '{self}': connection closed, stopping forwarding") ws = self._ws self._ws = None await self._call_event_handler("on_client_disconnected", ws) @@ -196,24 +196,24 @@ class WebSocketProxyServerTask(BaseTask): # Accept additional message types (e.g. BusFrameMessage). if self._forward_messages and isinstance(message, self._forward_messages): - logger.trace(f"Task '{self}': received {message} from client") + logger.trace(f"Worker '{self}': received {message} from client") await self.send_bus_message(message) continue - # Only accept other messages targeted at the local task. - if message.target != self._task_name: + # Only accept other messages targeted at the local worker. + if message.target != self._worker_name: logger.warning( - f"Task '{self}': dropped inbound message with " + f"Worker '{self}': dropped inbound message with " f"unexpected target '{message.target}'" ) continue - logger.trace(f"Task '{self}': received {message} from client") + logger.trace(f"Worker '{self}': received {message} from client") await self.send_bus_message(message) except Exception: - logger.exception(f"Task '{self}': failed to deserialize client message") + logger.exception(f"Worker '{self}': failed to deserialize client message") except WebSocketDisconnect: - logger.warning(f"Task '{self}': client disconnected") + logger.warning(f"Worker '{self}': client disconnected") ws = self._ws self._ws = None await self._call_event_handler("on_client_disconnected", ws) diff --git a/tests/test_app_resources.py b/tests/test_app_resources.py index 7eb1676d2..6c2d79497 100644 --- a/tests/test_app_resources.py +++ b/tests/test_app_resources.py @@ -15,7 +15,7 @@ from pipecat.adapters.schemas.direct_function import DirectFunctionWrapper from pipecat.clocks.system_clock import SystemClock from pipecat.frames.frames import EndFrame, Frame, StartFrame from pipecat.pipeline.pipeline import Pipeline -from pipecat.pipeline.task import PipelineTask, PipelineTaskParams +from pipecat.pipeline.worker import PipelineWorker, PipelineWorkerParams from pipecat.processors.aggregators.llm_context import LLMContext from pipecat.processors.frame_processor import FrameDirection, FrameProcessor, FrameProcessorSetup from pipecat.services.llm_service import ( @@ -64,7 +64,7 @@ class TestFunctionCallParamsAppResources(unittest.TestCase): tool_call_id="1", arguments={}, llm=None, # type: ignore[arg-type] - pipeline_task=None, # type: ignore[arg-type] + pipeline_worker=None, # type: ignore[arg-type] context=LLMContext(), result_callback=AsyncMock(), ) @@ -77,7 +77,7 @@ class TestFunctionCallParamsAppResources(unittest.TestCase): tool_call_id="1", arguments={}, llm=None, # type: ignore[arg-type] - pipeline_task=None, # type: ignore[arg-type] + pipeline_worker=None, # type: ignore[arg-type] context=LLMContext(), result_callback=AsyncMock(), app_resources=resources, @@ -91,7 +91,7 @@ class TestFunctionCallParamsAppResources(unittest.TestCase): tool_call_id="1", arguments={}, llm=None, # type: ignore[arg-type] - pipeline_task=None, # type: ignore[arg-type] + pipeline_worker=None, # type: ignore[arg-type] context=LLMContext(), result_callback=AsyncMock(), app_resources=resources, @@ -105,8 +105,8 @@ class TestLLMServiceFunctionCallReadsAppResources(unittest.IsolatedAsyncioTestCa async def test_function_call_params_receives_app_resources(self): service = _MockLLMService() resources = _Resources(user_name="John") - # Stub the pipeline task with just the bit LLMService reads. - service._pipeline_task = SimpleNamespace(app_resources=resources) # type: ignore[assignment] + # Stub the pipeline worker with just the bit LLMService reads. + service._pipeline_worker = SimpleNamespace(app_resources=resources) # type: ignore[assignment] captured: dict[str, Any] = {} @@ -137,7 +137,7 @@ class TestLLMServiceFunctionCallReadsAppResources(unittest.IsolatedAsyncioTestCa async def test_direct_function_params_receives_app_resources(self): service = _MockLLMService() resources = _Resources(user_name="John") - service._pipeline_task = SimpleNamespace(app_resources=resources) # type: ignore[assignment] + service._pipeline_worker = SimpleNamespace(app_resources=resources) # type: ignore[assignment] captured: dict[str, Any] = {} async def lookup(params: FunctionCallParams): @@ -174,7 +174,7 @@ class TestLLMServiceFunctionCallReadsAppResources(unittest.IsolatedAsyncioTestCa setup = FrameProcessorSetup( clock=SystemClock(), task_manager=task_manager, - pipeline_task=SimpleNamespace(app_resources=None), # type: ignore[arg-type] + pipeline_worker=SimpleNamespace(app_resources=None), # type: ignore[arg-type] tool_resources=resources, ) @@ -186,29 +186,29 @@ class TestLLMServiceFunctionCallReadsAppResources(unittest.IsolatedAsyncioTestCa class TestPipelineTaskAppResources(unittest.TestCase): def test_getter_returns_constructor_value(self): resources = _Resources(user_name="John") - task = PipelineTask(Pipeline([]), app_resources=resources) - self.assertIs(task.app_resources, resources) + worker = PipelineWorker(Pipeline([]), app_resources=resources) + self.assertIs(worker.app_resources, resources) def test_default_app_resources_is_none(self): - task = PipelineTask(Pipeline([])) - self.assertIsNone(task.app_resources) + worker = PipelineWorker(Pipeline([])) + self.assertIsNone(worker.app_resources) def test_tool_resources_kwarg_warns_and_aliases_app_resources(self): resources = _Resources(user_name="John") with self.assertWarns(DeprecationWarning): - task = PipelineTask(Pipeline([]), tool_resources=resources) - self.assertIs(task.app_resources, resources) + worker = PipelineWorker(Pipeline([]), tool_resources=resources) + self.assertIs(worker.app_resources, resources) def test_app_resources_takes_precedence_over_tool_resources(self): new = _Resources(user_name="new") old = _Resources(user_name="old") with self.assertWarns(DeprecationWarning): - task = PipelineTask(Pipeline([]), app_resources=new, tool_resources=old) - self.assertIs(task.app_resources, new) + worker = PipelineWorker(Pipeline([]), app_resources=new, tool_resources=old) + self.assertIs(worker.app_resources, new) class _RecordingProcessor(FrameProcessor): - """Records the pipeline_task it sees once StartFrame reaches it.""" + """Records the pipeline_worker it sees once StartFrame reaches it.""" def __init__(self): super().__init__() @@ -218,10 +218,10 @@ class _RecordingProcessor(FrameProcessor): async def process_frame(self, frame: Frame, direction: FrameDirection): await super().process_frame(frame, direction) if isinstance(frame, StartFrame): - # setup() runs before any frame reaches us, so pipeline_task is wired up. - assert self.pipeline_task is not None - self.observed_task = self.pipeline_task - self.observed_app_resources = self.pipeline_task.app_resources + # setup() runs before any frame reaches us, so pipeline_worker is wired up. + assert self.pipeline_worker is not None + self.observed_task = self.pipeline_worker + self.observed_app_resources = self.pipeline_worker.app_resources await self.push_frame(frame, direction) @@ -230,7 +230,7 @@ class _LegacyToolResourcesReader(FrameProcessor): Models a previously-written user FrameProcessor whose ``setup()`` override hasn't been migrated yet. The field is populated by - ``PipelineTask`` for backwards compatibility; reading it emits a + ``PipelineWorker`` for backwards compatibility; reading it emits a DeprecationWarning. """ @@ -244,7 +244,7 @@ class _LegacyToolResourcesReader(FrameProcessor): async def process_frame(self, frame: Frame, direction: FrameDirection): # Forward all frames so the EndFrame reaches the pipeline sink and - # ``task.run()`` can return cleanly. + # ``worker.run()`` can return cleanly. await super().process_frame(frame, direction) await self.push_frame(frame, direction) @@ -254,29 +254,29 @@ class TestFrameProcessorSetupToolResourcesBackwardsCompat(unittest.IsolatedAsync resources = _Resources(user_name="John") legacy = _LegacyToolResourcesReader() pipeline = Pipeline([legacy]) - task = PipelineTask(pipeline, app_resources=resources) + worker = PipelineWorker(pipeline, app_resources=resources) - await task.queue_frame(EndFrame()) + await worker.queue_frame(EndFrame()) with self.assertWarns(DeprecationWarning): - await task.run(PipelineTaskParams(loop=asyncio.get_event_loop())) + await worker.run(PipelineWorkerParams(loop=asyncio.get_event_loop())) self.assertIs(legacy.captured_tool_resources, resources) async def test_legacy_processor_receives_value_via_deprecated_tool_resources_kwarg( self, ): - # If the user is still constructing PipelineTask with the deprecated + # If the user is still constructing PipelineWorker with the deprecated # ``tool_resources`` kwarg (and hasn't migrated to ``app_resources``), # legacy processors must still see the value too. resources = _Resources(user_name="John") legacy = _LegacyToolResourcesReader() pipeline = Pipeline([legacy]) with self.assertWarns(DeprecationWarning): - task = PipelineTask(pipeline, tool_resources=resources) + worker = PipelineWorker(pipeline, tool_resources=resources) - await task.queue_frame(EndFrame()) + await worker.queue_frame(EndFrame()) with self.assertWarns(DeprecationWarning): - await task.run(PipelineTaskParams(loop=asyncio.get_event_loop())) + await worker.run(PipelineWorkerParams(loop=asyncio.get_event_loop())) self.assertIs(legacy.captured_tool_resources, resources) @@ -286,18 +286,18 @@ class TestFrameProcessorPipelineTaskAccess(unittest.IsolatedAsyncioTestCase): resources = _Resources(user_name="John") recorder = _RecordingProcessor() pipeline = Pipeline([recorder]) - task = PipelineTask(pipeline, app_resources=resources) + worker = PipelineWorker(pipeline, app_resources=resources) - await task.queue_frame(EndFrame()) - await task.run(PipelineTaskParams(loop=asyncio.get_event_loop())) + await worker.queue_frame(EndFrame()) + await worker.run(PipelineWorkerParams(loop=asyncio.get_event_loop())) - self.assertIs(recorder.observed_task, task) + self.assertIs(recorder.observed_task, worker) self.assertIs(recorder.observed_app_resources, resources) def test_pipeline_task_raises_when_not_set_up(self): recorder = _RecordingProcessor() with self.assertRaises(Exception): - _ = recorder.pipeline_task + _ = recorder.pipeline_worker if __name__ == "__main__": diff --git a/tests/test_audio_buffer_processor.py b/tests/test_audio_buffer_processor.py index 5b5f9996d..b1b71758c 100644 --- a/tests/test_audio_buffer_processor.py +++ b/tests/test_audio_buffer_processor.py @@ -49,7 +49,7 @@ async def _make_processor(*, buffer_size: int = 0) -> AudioBufferProcessor: FrameProcessorSetup( clock=SystemClock(), task_manager=task_manager, - pipeline_task=SimpleNamespace(app_resources=None), # type: ignore[arg-type] + pipeline_worker=SimpleNamespace(app_resources=None), # type: ignore[arg-type] ) ) diff --git a/tests/test_base_task.py b/tests/test_base_worker.py similarity index 70% rename from tests/test_base_task.py rename to tests/test_base_worker.py index 68dae036c..6add7c4bd 100644 --- a/tests/test_base_task.py +++ b/tests/test_base_worker.py @@ -9,13 +9,13 @@ import unittest from pipecat.bus import ( AsyncQueueBus, - BusActivateTaskMessage, - BusAddTaskMessage, + BusActivateWorkerMessage, + BusAddWorkerMessage, BusCancelMessage, - BusCancelTaskMessage, - BusDeactivateTaskMessage, + BusCancelWorkerMessage, + BusDeactivateWorkerMessage, BusEndMessage, - BusEndTaskMessage, + BusEndWorkerMessage, BusFrameMessage, BusJobCancelMessage, BusJobRequestMessage, @@ -26,16 +26,16 @@ from pipecat.bus import ( BusJobUpdateMessage, ) from pipecat.frames.frames import EndFrame, Frame, TextFrame -from pipecat.pipeline.base_task import BaseTask +from pipecat.pipeline.base_worker import BaseWorker from pipecat.pipeline.job_context import JobStatus from pipecat.pipeline.job_decorator import job from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.runner import PipelineRunner -from pipecat.pipeline.task import PipelineTask +from pipecat.pipeline.worker import PipelineWorker from pipecat.processors.filters.identity_filter import IdentityFilter from pipecat.processors.frame_processor import FrameDirection, FrameProcessor -from pipecat.registry import TaskRegistry -from pipecat.registry.types import TaskReadyData +from pipecat.registry import WorkerRegistry +from pipecat.registry.types import WorkerReadyData from pipecat.utils.asyncio.task_manager import TaskManager, TaskManagerParams @@ -60,14 +60,14 @@ async def create_test_bus(): def create_test_registry(): - """Create a registry for testing task lifecycle.""" - return TaskRegistry(runner_name="test-runner") + """Create a registry for testing worker lifecycle.""" + return WorkerRegistry(runner_name="test-runner") async def register_tasks(registry, *names): - """Pre-register task names so the ready-wait completes immediately.""" + """Pre-register worker names so the ready-wait completes immediately.""" for name in names: - await registry.register(TaskReadyData(task_name=name, runner="test-runner")) + await registry.register(WorkerReadyData(worker_name=name, runner="test-runner")) def capture_bus(bus): @@ -84,8 +84,8 @@ def capture_bus(bus): def make_stub_pipeline_task(name, *, bridged=None, active=True): - """Create a PipelineTask with an IdentityFilter pipeline.""" - return PipelineTask( + """Create a PipelineWorker with an IdentityFilter pipeline.""" + return PipelineWorker( Pipeline([IdentityFilter()]), name=name, bridged=bridged, @@ -99,23 +99,23 @@ class TestPipelineTaskLifecycle(unittest.IsolatedAsyncioTestCase): self.registry = create_test_registry() async def test_task_starts_inactive_by_default(self): - """Bridged task is inactive by default.""" - task = make_stub_pipeline_task("test", bridged=()) - task._active = False - task._pending_activation = False - self.assertFalse(task.active) + """Bridged worker is inactive by default.""" + worker = make_stub_pipeline_task("test", bridged=()) + worker._active = False + worker._pending_activation = False + self.assertFalse(worker.active) async def test_handoff_via_bus_message_after_pipeline_start(self): - """Task activates when BusActivateTaskMessage received and pipeline started.""" - task = make_stub_pipeline_task("test", bridged=()) - task._active = False - task._pending_activation = False - task.attach(registry=self.registry, bus=self.bus) + """Task activates when BusActivateWorkerMessage received and pipeline started.""" + worker = make_stub_pipeline_task("test", bridged=()) + worker._active = False + worker._pending_activation = False + worker.attach(registry=self.registry, bus=self.bus) handoff_done = asyncio.Event() handoff_args_received = [] - @task.event_handler("on_activated") + @worker.event_handler("on_activated") async def on_handoff(t, args): handoff_args_received.append(args) handoff_done.set() @@ -124,51 +124,51 @@ class TestPipelineTaskLifecycle(unittest.IsolatedAsyncioTestCase): async def handoff_after_start(): await asyncio.sleep(0.05) - await self.bus.send(BusActivateTaskMessage(source="other", target="test", args=args)) + await self.bus.send(BusActivateWorkerMessage(source="other", target="test", args=args)) await asyncio.wait_for(handoff_done.wait(), timeout=2.0) - await task.queue_frame(EndFrame()) + await worker.queue_frame(EndFrame()) runner = PipelineRunner(bus=self.bus, handle_sigint=False) - await asyncio.gather(runner.run(task), handoff_after_start()) + await asyncio.gather(runner.run(worker), handoff_after_start()) - self.assertTrue(task.active) + self.assertTrue(worker.active) self.assertEqual(len(handoff_args_received), 1) self.assertEqual(handoff_args_received[0], args) async def test_active_true_fires_on_activated(self): """active=True fires on_activated after pipeline starts.""" - task = make_stub_pipeline_task("test", bridged=()) + worker = make_stub_pipeline_task("test", bridged=()) activated = asyncio.Event() - @task.event_handler("on_activated") + @worker.event_handler("on_activated") async def on_activated(t, args): activated.set() async def wait_and_end(): await asyncio.wait_for(activated.wait(), timeout=2.0) - await task.queue_frame(EndFrame()) + await worker.queue_frame(EndFrame()) runner = PipelineRunner(bus=self.bus, handle_sigint=False) - await asyncio.gather(runner.run(task), wait_and_end()) + await asyncio.gather(runner.run(worker), wait_and_end()) - self.assertTrue(task.active) + self.assertTrue(worker.active) self.assertTrue(activated.is_set()) async def test_activation_args_property_set_and_cleared(self): """activation_args returns the latest args while active and is cleared on deactivate.""" - task = make_stub_pipeline_task("test", bridged=()) - task._active = False - task._pending_activation = False + worker = make_stub_pipeline_task("test", bridged=()) + worker._active = False + worker._pending_activation = False activated = asyncio.Event() deactivated = asyncio.Event() - @task.event_handler("on_activated") + @worker.event_handler("on_activated") async def _on_activated(t, args): activated.set() - @task.event_handler("on_deactivated") + @worker.event_handler("on_deactivated") async def _on_deactivated(t): deactivated.set() @@ -177,42 +177,42 @@ class TestPipelineTaskLifecycle(unittest.IsolatedAsyncioTestCase): async def drive(): await asyncio.sleep(0.05) - await self.bus.send(BusActivateTaskMessage(source="other", target="test", args=args)) + await self.bus.send(BusActivateWorkerMessage(source="other", target="test", args=args)) await asyncio.wait_for(activated.wait(), timeout=2.0) - observed_while_active["args"] = task.activation_args - observed_while_active["active"] = task.active - await self.bus.send(BusDeactivateTaskMessage(source="other", target="test")) + observed_while_active["args"] = worker.activation_args + observed_while_active["active"] = worker.active + await self.bus.send(BusDeactivateWorkerMessage(source="other", target="test")) await asyncio.wait_for(deactivated.wait(), timeout=2.0) - await task.queue_frame(EndFrame()) + await worker.queue_frame(EndFrame()) runner = PipelineRunner(bus=self.bus, handle_sigint=False) - await asyncio.gather(runner.run(task), drive()) + await asyncio.gather(runner.run(worker), drive()) self.assertTrue(observed_while_active["active"]) self.assertEqual(observed_while_active["args"], args) - self.assertFalse(task.active) - self.assertIsNone(task.activation_args) + self.assertFalse(worker.active) + self.assertIsNone(worker.activation_args) async def test_activation_args_none_before_activation(self): """activation_args is None before any activation has occurred.""" - task = make_stub_pipeline_task("test", bridged=()) - task._active = False - task._pending_activation = False - self.assertIsNone(task.activation_args) + worker = make_stub_pipeline_task("test", bridged=()) + worker._active = False + worker._pending_activation = False + self.assertIsNone(worker.activation_args) async def test_activate_task_with_deactivate_self_sends_both_messages(self): - """activate_task(deactivate_self=True) sends deactivate then activate.""" + """activate_worker(deactivate_self=True) sends deactivate then activate.""" sent = capture_bus(self.bus) - task = make_stub_pipeline_task("task_a", bridged=()) - task.attach(registry=self.registry, bus=self.bus) + worker = make_stub_pipeline_task("task_a", bridged=()) + worker.attach(registry=self.registry, bus=self.bus) - await task.activate_task("task_b", deactivate_self=True) + await worker.activate_worker("task_b", deactivate_self=True) - deactivate_msgs = [m for m in sent if isinstance(m, BusDeactivateTaskMessage)] + deactivate_msgs = [m for m in sent if isinstance(m, BusDeactivateWorkerMessage)] self.assertEqual(len(deactivate_msgs), 1) self.assertEqual(deactivate_msgs[0].target, "task_a") - activate_msgs = [m for m in sent if isinstance(m, BusActivateTaskMessage)] + activate_msgs = [m for m in sent if isinstance(m, BusActivateWorkerMessage)] self.assertEqual(len(activate_msgs), 1) self.assertEqual(activate_msgs[0].target, "task_b") @@ -220,9 +220,9 @@ class TestPipelineTaskLifecycle(unittest.IsolatedAsyncioTestCase): """end() with no parent sends BusEndMessage.""" sent = capture_bus(self.bus) - task = BaseTask("task_a") - task.attach(registry=self.registry, bus=self.bus) - await task.end(reason="done") + worker = BaseWorker("task_a") + worker.attach(registry=self.registry, bus=self.bus) + await worker.end(reason="done") end_msgs = [m for m in sent if isinstance(m, BusEndMessage)] self.assertEqual(len(end_msgs), 1) @@ -233,12 +233,12 @@ class TestPipelineTaskLifecycle(unittest.IsolatedAsyncioTestCase): """end() with parent still sends BusEndMessage (runner handles it).""" sent = capture_bus(self.bus) - parent = BaseTask("parent_task") + parent = BaseWorker("parent_task") parent.attach(registry=self.registry, bus=self.bus) - task = BaseTask("child") - task.attach(registry=self.registry, bus=self.bus) - await parent.add_task(task) - await task.end(reason="goodbye") + worker = BaseWorker("child") + worker.attach(registry=self.registry, bus=self.bus) + await parent.add_worker(worker) + await worker.end(reason="goodbye") end_msgs = [m for m in sent if isinstance(m, BusEndMessage)] self.assertEqual(len(end_msgs), 1) @@ -249,107 +249,107 @@ class TestPipelineTaskLifecycle(unittest.IsolatedAsyncioTestCase): """cancel() sends BusCancelMessage.""" sent = capture_bus(self.bus) - task = BaseTask("task_a") - task.attach(registry=self.registry, bus=self.bus) - await task.cancel() + worker = BaseWorker("task_a") + worker.attach(registry=self.registry, bus=self.bus) + await worker.cancel() cancel_msgs = [m for m in sent if isinstance(m, BusCancelMessage)] self.assertEqual(len(cancel_msgs), 1) self.assertEqual(cancel_msgs[0].source, "task_a") async def test_add_task_sends_bus_add_task_message(self): - """add_task() sends BusAddTaskMessage.""" + """add_worker() sends BusAddWorkerMessage.""" sent = capture_bus(self.bus) - task = BaseTask("task_a") - task.attach(registry=self.registry, bus=self.bus) - new_task = BaseTask("task_b") - await task.add_task(new_task) + worker = BaseWorker("task_a") + worker.attach(registry=self.registry, bus=self.bus) + new_task = BaseWorker("task_b") + await worker.add_worker(new_task) - add_msgs = [m for m in sent if isinstance(m, BusAddTaskMessage)] + add_msgs = [m for m in sent if isinstance(m, BusAddWorkerMessage)] self.assertEqual(len(add_msgs), 1) - self.assertIs(add_msgs[0].task, new_task) + self.assertIs(add_msgs[0].worker, new_task) async def test_started_at_none_before_pipeline_starts(self): """started_at is None before the pipeline has started.""" - task = make_stub_pipeline_task("test") - self.assertIsNone(task.started_at) + worker = make_stub_pipeline_task("test") + self.assertIsNone(worker.started_at) async def test_started_at_set_after_pipeline_starts(self): """started_at becomes set once the pipeline starts.""" - task = make_stub_pipeline_task("test") + worker = make_stub_pipeline_task("test") ready_event = asyncio.Event() - @task.event_handler("on_pipeline_started") + @worker.event_handler("on_pipeline_started") async def _on_started(t, frame): ready_event.set() async def wait_and_end(): await asyncio.wait_for(ready_event.wait(), timeout=2.0) - self.assertIsNotNone(task.started_at) - await task.queue_frame(EndFrame()) + self.assertIsNotNone(worker.started_at) + await worker.queue_frame(EndFrame()) runner = PipelineRunner(bus=self.bus, handle_sigint=False) - await asyncio.gather(runner.run(task), wait_and_end()) + await asyncio.gather(runner.run(worker), wait_and_end()) async def test_on_pipeline_started_event(self): """on_pipeline_started fires after pipeline starts.""" - task = make_stub_pipeline_task("test") + worker = make_stub_pipeline_task("test") started = asyncio.Event() - @task.event_handler("on_pipeline_started") + @worker.event_handler("on_pipeline_started") async def on_started(t, frame): started.set() async def wait_and_end(): await asyncio.wait_for(started.wait(), timeout=2.0) - await task.queue_frame(EndFrame()) + await worker.queue_frame(EndFrame()) runner = PipelineRunner(bus=self.bus, handle_sigint=False) - await asyncio.gather(runner.run(task), wait_and_end()) + await asyncio.gather(runner.run(worker), wait_and_end()) self.assertTrue(started.is_set()) async def test_on_pipeline_finished_event(self): """on_pipeline_finished fires after pipeline finishes.""" - task = make_stub_pipeline_task("test") + worker = make_stub_pipeline_task("test") finished_fired = asyncio.Event() - @task.event_handler("on_pipeline_finished") + @worker.event_handler("on_pipeline_finished") async def on_finished(t, frame): finished_fired.set() async def end_pipeline(): await asyncio.sleep(0.05) - await task.queue_frame(EndFrame()) + await worker.queue_frame(EndFrame()) runner = PipelineRunner(bus=self.bus, handle_sigint=False) - await asyncio.gather(runner.run(task), end_pipeline()) + await asyncio.gather(runner.run(worker), end_pipeline()) self.assertTrue(finished_fired.is_set()) async def test_activate_task_with_deactivate_self_deactivates(self): - """activate_task(deactivate_self=True) sends a deactivate for the calling task.""" + """activate_worker(deactivate_self=True) sends a deactivate for the calling worker.""" sent = capture_bus(self.bus) - task = make_stub_pipeline_task("test", bridged=()) - task.attach(registry=self.registry, bus=self.bus) + worker = make_stub_pipeline_task("test", bridged=()) + worker.attach(registry=self.registry, bus=self.bus) - self.assertTrue(task.active) - await task.activate_task("other", deactivate_self=True) - deactivate_msgs = [m for m in sent if isinstance(m, BusDeactivateTaskMessage)] + self.assertTrue(worker.active) + await worker.activate_worker("other", deactivate_self=True) + deactivate_msgs = [m for m in sent if isinstance(m, BusDeactivateWorkerMessage)] self.assertEqual(len(deactivate_msgs), 1) self.assertEqual(deactivate_msgs[0].target, "test") async def test_bus_end_task_message_ends_pipeline(self): - """BusEndTaskMessage causes the pipeline to end gracefully.""" - task = make_stub_pipeline_task("test") + """BusEndWorkerMessage causes the pipeline to end gracefully.""" + worker = make_stub_pipeline_task("test") finished = asyncio.Event() - @task.event_handler("on_pipeline_finished") + @worker.event_handler("on_pipeline_finished") async def on_finished(t, frame): if isinstance(frame, EndFrame): finished.set() @@ -357,84 +357,84 @@ class TestPipelineTaskLifecycle(unittest.IsolatedAsyncioTestCase): async def send_end_message(): await asyncio.sleep(0.05) await self.bus.send( - BusEndTaskMessage(source="runner", target="test", reason="shutdown") + BusEndWorkerMessage(source="runner", target="test", reason="shutdown") ) runner = PipelineRunner(bus=self.bus, handle_sigint=False) - await asyncio.gather(runner.run(task), send_end_message()) + await asyncio.gather(runner.run(worker), send_end_message()) self.assertTrue(finished.is_set()) async def test_bus_cancel_task_message_cancels_pipeline(self): - """BusCancelTaskMessage cancels the pipeline task.""" - task = make_stub_pipeline_task("test") + """BusCancelWorkerMessage cancels the pipeline worker.""" + worker = make_stub_pipeline_task("test") async def send_cancel_message(): await asyncio.sleep(0.05) - await self.bus.send(BusCancelTaskMessage(source="runner", target="test")) + await self.bus.send(BusCancelWorkerMessage(source="runner", target="test")) runner = PipelineRunner(bus=self.bus, handle_sigint=False) try: - await asyncio.gather(runner.run(task), send_cancel_message()) + await asyncio.gather(runner.run(worker), send_cancel_message()) except asyncio.CancelledError: pass - self.assertTrue(task.has_finished()) + self.assertTrue(worker.has_finished()) async def test_queue_frame(self): """queue_frame injects a frame into the pipeline.""" - task = make_stub_pipeline_task("test") + worker = make_stub_pipeline_task("test") received = [] - task.set_reached_downstream_filter((TextFrame,)) + worker.set_reached_downstream_filter((TextFrame,)) - @task.event_handler("on_frame_reached_downstream") + @worker.event_handler("on_frame_reached_downstream") async def on_frame(t, frame): received.append(frame) async def push_frames(): await asyncio.sleep(0.05) - await task.queue_frame(TextFrame(text="injected")) + await worker.queue_frame(TextFrame(text="injected")) await asyncio.sleep(0.05) - await task.queue_frame(EndFrame()) + await worker.queue_frame(EndFrame()) runner = PipelineRunner(bus=self.bus, handle_sigint=False) - await asyncio.gather(runner.run(task), push_frames()) + await asyncio.gather(runner.run(worker), push_frames()) self.assertEqual(len(received), 1) self.assertEqual(received[0].text, "injected") async def test_queue_frames(self): """queue_frames injects multiple frames into the pipeline.""" - task = make_stub_pipeline_task("test") + worker = make_stub_pipeline_task("test") received = [] - task.set_reached_downstream_filter((TextFrame,)) + worker.set_reached_downstream_filter((TextFrame,)) - @task.event_handler("on_frame_reached_downstream") + @worker.event_handler("on_frame_reached_downstream") async def on_frame(t, frame): received.append(frame) async def push_frames(): await asyncio.sleep(0.05) - await task.queue_frames([TextFrame(text="a"), TextFrame(text="b")]) + await worker.queue_frames([TextFrame(text="a"), TextFrame(text="b")]) await asyncio.sleep(0.05) - await task.queue_frame(EndFrame()) + await worker.queue_frame(EndFrame()) runner = PipelineRunner(bus=self.bus, handle_sigint=False) - await asyncio.gather(runner.run(task), push_frames()) + await asyncio.gather(runner.run(worker), push_frames()) self.assertEqual(len(received), 2) self.assertEqual(received[0].text, "a") self.assertEqual(received[1].text, "b") async def test_self_handoff(self): - """A task can hand off to itself via activate_task(self.name, deactivate_self=True).""" - task = make_stub_pipeline_task("test", bridged=()) + """A worker can hand off to itself via activate_worker(self.name, deactivate_self=True).""" + worker = make_stub_pipeline_task("test", bridged=()) handoff_done = asyncio.Event() - @task.event_handler("on_activated") + @worker.event_handler("on_activated") async def on_handoff(t, args): handoff_done.set() @@ -442,59 +442,59 @@ class TestPipelineTaskLifecycle(unittest.IsolatedAsyncioTestCase): # Wait for first activation (from active=True) await asyncio.sleep(0.05) handoff_done.clear() - await task.activate_task("test", deactivate_self=True) + await worker.activate_worker("test", deactivate_self=True) await asyncio.wait_for(handoff_done.wait(), timeout=2.0) - await task.queue_frame(EndFrame()) + await worker.queue_frame(EndFrame()) runner = PipelineRunner(bus=self.bus, handle_sigint=False) - await asyncio.gather(runner.run(task), self_handoff()) + await asyncio.gather(runner.run(worker), self_handoff()) - self.assertTrue(task.active) + self.assertTrue(worker.active) async def test_add_task_tracks_children(self): - """add_task() populates children list and sets parent.""" - parent = BaseTask("parent") + """add_worker() populates children list and sets parent.""" + parent = BaseWorker("parent") parent.attach(registry=self.registry, bus=self.bus) - child_a = BaseTask("child_a") - child_b = BaseTask("child_b") + child_a = BaseWorker("child_a") + child_b = BaseWorker("child_b") - await parent.add_task(child_a) - await parent.add_task(child_b) + await parent.add_worker(child_a) + await parent.add_worker(child_b) self.assertEqual(len(parent.children), 2) self.assertIs(parent.children[0], child_a) self.assertIs(parent.children[1], child_b) async def test_end_propagates_to_children(self): - """BusEndTaskMessage on parent sends end to each child.""" + """BusEndWorkerMessage on parent sends end to each child.""" sent = capture_bus(self.bus) - parent = BaseTask("parent") + parent = BaseWorker("parent") parent.attach(registry=self.registry, bus=self.bus) - child_a = BaseTask("child_a") - child_b = BaseTask("child_b") - await parent.add_task(child_a) - await parent.add_task(child_b) + child_a = BaseWorker("child_a") + child_b = BaseWorker("child_b") + await parent.add_worker(child_a) + await parent.add_worker(child_b) # Pre-set children as finished so gather returns immediately child_a._finished_event.set() child_b._finished_event.set() await parent.on_bus_message( - BusEndTaskMessage(source="runner", target="parent", reason="shutdown") + BusEndWorkerMessage(source="runner", target="parent", reason="shutdown") ) - end_msgs = [m for m in sent if isinstance(m, BusEndTaskMessage)] + end_msgs = [m for m in sent if isinstance(m, BusEndWorkerMessage)] targets = {m.target for m in end_msgs} self.assertIn("child_a", targets) self.assertIn("child_b", targets) async def test_end_waits_for_children(self): - """Parent waits for children to finish before completing _handle_task_end.""" - parent = BaseTask("parent") + """Parent waits for children to finish before completing _handle_worker_end.""" + parent = BaseWorker("parent") parent.attach(registry=self.registry, bus=self.bus) - child = BaseTask("child") - await parent.add_task(child) + child = BaseWorker("child") + await parent.add_worker(child) order = [] @@ -506,7 +506,7 @@ class TestPipelineTaskLifecycle(unittest.IsolatedAsyncioTestCase): async def send_end(): await asyncio.sleep(0.05) await parent.on_bus_message( - BusEndTaskMessage(source="runner", target="parent", reason="shutdown") + BusEndWorkerMessage(source="runner", target="parent", reason="shutdown") ) order.append("parent_end_returned") @@ -516,29 +516,29 @@ class TestPipelineTaskLifecycle(unittest.IsolatedAsyncioTestCase): self.assertEqual(order, ["child_finished", "parent_end_returned"]) async def test_cancel_propagates_to_children(self): - """BusCancelTaskMessage on parent sends cancel to each child.""" + """BusCancelWorkerMessage on parent sends cancel to each child.""" sent = capture_bus(self.bus) - parent = BaseTask("parent") + parent = BaseWorker("parent") parent.attach(registry=self.registry, bus=self.bus) - child_a = BaseTask("child_a") - child_b = BaseTask("child_b") - await parent.add_task(child_a) - await parent.add_task(child_b) + child_a = BaseWorker("child_a") + child_b = BaseWorker("child_b") + await parent.add_worker(child_a) + await parent.add_worker(child_b) await parent.on_bus_message( - BusCancelTaskMessage(source="runner", target="parent", reason="abort") + BusCancelWorkerMessage(source="runner", target="parent", reason="abort") ) - cancel_msgs = [m for m in sent if isinstance(m, BusCancelTaskMessage)] + cancel_msgs = [m for m in sent if isinstance(m, BusCancelWorkerMessage)] targets = {m.target for m in cancel_msgs} self.assertIn("child_a", targets) self.assertIn("child_b", targets) def make_generating_task(name, *, bridged=None): - """Create a PipelineTask whose pipeline generates frames.""" - return PipelineTask( + """Create a PipelineWorker whose pipeline generates frames.""" + return PipelineWorker( Pipeline([_FrameGenerator()]), name=name, bridged=bridged, @@ -555,32 +555,32 @@ class TestEdgeToBus(unittest.IsolatedAsyncioTestCase): """Pipeline-generated frames are broadcast to the bus.""" sent = capture_bus(self.bus) - task = make_generating_task("task", bridged=()) + worker = make_generating_task("worker", bridged=()) async def push_frames(): await asyncio.sleep(0.05) - await task.queue_frame(TextFrame(text="input")) + await worker.queue_frame(TextFrame(text="input")) await asyncio.sleep(0.05) - await task.queue_frame(EndFrame()) + await worker.queue_frame(EndFrame()) runner = PipelineRunner(bus=self.bus, handle_sigint=False) - await asyncio.gather(runner.run(task), push_frames()) + await asyncio.gather(runner.run(worker), push_frames()) bus_frame_msgs = [m for m in sent if isinstance(m, BusFrameMessage)] text_msgs = [m for m in bus_frame_msgs if isinstance(m.frame, TextFrame)] generated = [m for m in text_msgs if m.frame.text == "generated_input"] self.assertEqual(len(generated), 1) - self.assertEqual(generated[0].source, "task") + self.assertEqual(generated[0].source, "worker") async def test_bus_frames_not_rebroadcast_by_same_task(self): """Frames from the bus with source==self are ignored by edge processors.""" sent = capture_bus(self.bus) - task = make_stub_pipeline_task("task", bridged=()) + worker = make_stub_pipeline_task("worker", bridged=()) async def inject_frame(): await asyncio.sleep(0.05) - # Send a frame from "other" — edge source accepts it (downstream, source != task) + # Send a frame from "other" — edge source accepts it (downstream, source != worker) await self.bus.send( BusFrameMessage( source="other", @@ -589,53 +589,53 @@ class TestEdgeToBus(unittest.IsolatedAsyncioTestCase): ) ) await asyncio.sleep(0.05) - await task.queue_frame(EndFrame()) + await worker.queue_frame(EndFrame()) runner = PipelineRunner(bus=self.bus, handle_sigint=False) - await asyncio.gather(runner.run(task), inject_frame()) + await asyncio.gather(runner.run(worker), inject_frame()) # The frame passes through the identity pipeline and reaches - # EdgeSink, which re-broadcasts with source="task". That's + # EdgeSink, which re-broadcasts with source="worker". That's # expected. But it must NOT create a loop — EdgeSource ignores - # it because source == "task". + # it because source == "worker". # Filter to TextFrame only to ignore metrics frames. bus_frame_msgs = [ m for m in sent if isinstance(m, BusFrameMessage) and isinstance(m.frame, TextFrame) ] - from_task = [m for m in bus_frame_msgs if m.source == "task"] + from_task = [m for m in bus_frame_msgs if m.source == "worker"] from_other = [m for m in bus_frame_msgs if m.source == "other"] - # One re-broadcast from task (EdgeSink), one original from other + # One re-broadcast from worker (EdgeSink), one original from other self.assertEqual(len(from_other), 1) self.assertEqual(len(from_task), 1) # No infinite loop — total is exactly 2 self.assertEqual(len(bus_frame_msgs), 2) async def test_unbridged_task_no_edge_sinks(self): - """An unbridged PipelineTask does not tee frames to the bus.""" + """An unbridged PipelineWorker does not tee frames to the bus.""" sent = capture_bus(self.bus) - task = make_stub_pipeline_task("root", bridged=None) + worker = make_stub_pipeline_task("root", bridged=None) async def push_frames(): await asyncio.sleep(0.05) - await task.queue_frame(TextFrame(text="root_frame")) + await worker.queue_frame(TextFrame(text="root_frame")) await asyncio.sleep(0.05) - await task.queue_frame(EndFrame()) + await worker.queue_frame(EndFrame()) runner = PipelineRunner(bus=self.bus, handle_sigint=False) - await asyncio.gather(runner.run(task), push_frames()) + await asyncio.gather(runner.run(worker), push_frames()) bus_frame_msgs = [m for m in sent if isinstance(m, BusFrameMessage)] self.assertEqual(len(bus_frame_msgs), 0) async def test_bus_frame_enters_task_pipeline(self): """Bus frame messages enter the pipeline via edge source processor.""" - task = make_stub_pipeline_task("task", bridged=()) + worker = make_stub_pipeline_task("worker", bridged=()) received = [] - task.set_reached_downstream_filter((TextFrame,)) + worker.set_reached_downstream_filter((TextFrame,)) - @task.event_handler("on_frame_reached_downstream") + @worker.event_handler("on_frame_reached_downstream") async def on_frame(t, frame): received.append(frame) @@ -649,10 +649,10 @@ class TestEdgeToBus(unittest.IsolatedAsyncioTestCase): ) ) await asyncio.sleep(0.05) - await task.queue_frame(EndFrame()) + await worker.queue_frame(EndFrame()) runner = PipelineRunner(bus=self.bus, handle_sigint=False) - await asyncio.gather(runner.run(task), inject_frame()) + await asyncio.gather(runner.run(worker), inject_frame()) self.assertEqual(len(received), 1) self.assertEqual(received[0].text, "from_bus") @@ -661,16 +661,16 @@ class TestEdgeToBus(unittest.IsolatedAsyncioTestCase): """Direction is preserved when generated frames are sent to the bus.""" sent = capture_bus(self.bus) - task = make_generating_task("task", bridged=()) + worker = make_generating_task("worker", bridged=()) async def push_frames(): await asyncio.sleep(0.05) - await task.queue_frame(TextFrame(text="hello")) + await worker.queue_frame(TextFrame(text="hello")) await asyncio.sleep(0.05) - await task.queue_frame(EndFrame()) + await worker.queue_frame(EndFrame()) runner = PipelineRunner(bus=self.bus, handle_sigint=False) - await asyncio.gather(runner.run(task), push_frames()) + await asyncio.gather(runner.run(worker), push_frames()) bus_frame_msgs = [m for m in sent if isinstance(m, BusFrameMessage)] text_msgs = [m for m in bus_frame_msgs if isinstance(m.frame, TextFrame)] @@ -679,13 +679,13 @@ class TestEdgeToBus(unittest.IsolatedAsyncioTestCase): self.assertEqual(generated[0].direction, FrameDirection.DOWNSTREAM) async def test_bridged_task_accepts_matching_bridge(self): - """Bridged task with named bridge accepts frames from that bridge.""" - task = make_stub_pipeline_task("task", bridged=("voice",)) + """Bridged worker with named bridge accepts frames from that bridge.""" + worker = make_stub_pipeline_task("worker", bridged=("voice",)) received = [] - task.set_reached_downstream_filter((TextFrame,)) + worker.set_reached_downstream_filter((TextFrame,)) - @task.event_handler("on_frame_reached_downstream") + @worker.event_handler("on_frame_reached_downstream") async def on_frame(t, frame): received.append(frame) @@ -700,22 +700,22 @@ class TestEdgeToBus(unittest.IsolatedAsyncioTestCase): ) ) await asyncio.sleep(0.05) - await task.queue_frame(EndFrame()) + await worker.queue_frame(EndFrame()) runner = PipelineRunner(bus=self.bus, handle_sigint=False) - await asyncio.gather(runner.run(task), inject_frame()) + await asyncio.gather(runner.run(worker), inject_frame()) self.assertEqual(len(received), 1) self.assertEqual(received[0].text, "voice_frame") async def test_bridged_task_rejects_non_matching_bridge(self): - """Bridged task with named bridge rejects frames from other bridges.""" - task = make_stub_pipeline_task("task", bridged=("voice",)) + """Bridged worker with named bridge rejects frames from other bridges.""" + worker = make_stub_pipeline_task("worker", bridged=("voice",)) received = [] - task.set_reached_downstream_filter((TextFrame,)) + worker.set_reached_downstream_filter((TextFrame,)) - @task.event_handler("on_frame_reached_downstream") + @worker.event_handler("on_frame_reached_downstream") async def on_frame(t, frame): received.append(frame) @@ -730,21 +730,21 @@ class TestEdgeToBus(unittest.IsolatedAsyncioTestCase): ) ) await asyncio.sleep(0.05) - await task.queue_frame(EndFrame()) + await worker.queue_frame(EndFrame()) runner = PipelineRunner(bus=self.bus, handle_sigint=False) - await asyncio.gather(runner.run(task), inject_frame()) + await asyncio.gather(runner.run(worker), inject_frame()) self.assertEqual(len(received), 0) async def test_bridged_task_empty_tuple_accepts_all(self): - """Bridged task with empty tuple accepts frames from any bridge.""" - task = make_stub_pipeline_task("task", bridged=()) + """Bridged worker with empty tuple accepts frames from any bridge.""" + worker = make_stub_pipeline_task("worker", bridged=()) received = [] - task.set_reached_downstream_filter((TextFrame,)) + worker.set_reached_downstream_filter((TextFrame,)) - @task.event_handler("on_frame_reached_downstream") + @worker.event_handler("on_frame_reached_downstream") async def on_frame(t, frame): received.append(frame) @@ -774,21 +774,21 @@ class TestEdgeToBus(unittest.IsolatedAsyncioTestCase): ) ) await asyncio.sleep(0.05) - await task.queue_frame(EndFrame()) + await worker.queue_frame(EndFrame()) runner = PipelineRunner(bus=self.bus, handle_sigint=False) - await asyncio.gather(runner.run(task), inject_frames()) + await asyncio.gather(runner.run(worker), inject_frames()) self.assertEqual(len(received), 3) async def test_bridged_task_multiple_bridges(self): - """Bridged task with multiple bridge names accepts from all listed.""" - task = make_stub_pipeline_task("task", bridged=("voice", "video")) + """Bridged worker with multiple bridge names accepts from all listed.""" + worker = make_stub_pipeline_task("worker", bridged=("voice", "video")) received = [] - task.set_reached_downstream_filter((TextFrame,)) + worker.set_reached_downstream_filter((TextFrame,)) - @task.event_handler("on_frame_reached_downstream") + @worker.event_handler("on_frame_reached_downstream") async def on_frame(t, frame): received.append(frame) @@ -819,28 +819,28 @@ class TestEdgeToBus(unittest.IsolatedAsyncioTestCase): ) ) await asyncio.sleep(0.05) - await task.queue_frame(EndFrame()) + await worker.queue_frame(EndFrame()) runner = PipelineRunner(bus=self.bus, handle_sigint=False) - await asyncio.gather(runner.run(task), inject_frames()) + await asyncio.gather(runner.run(worker), inject_frames()) texts = sorted([r.text for r in received]) self.assertEqual(texts, ["video", "voice"]) async def test_not_bridged_task_ignores_bridge(self): - """Non-bridged task (bridged=None) has no edge processors.""" + """Non-bridged worker (bridged=None) has no edge processors.""" sent = capture_bus(self.bus) - task = make_stub_pipeline_task("root", bridged=None) + worker = make_stub_pipeline_task("root", bridged=None) async def push_frames(): await asyncio.sleep(0.05) - await task.queue_frame(TextFrame(text="test")) + await worker.queue_frame(TextFrame(text="test")) await asyncio.sleep(0.05) - await task.queue_frame(EndFrame()) + await worker.queue_frame(EndFrame()) runner = PipelineRunner(bus=self.bus, handle_sigint=False) - await asyncio.gather(runner.run(task), push_frames()) + await asyncio.gather(runner.run(worker), push_frames()) bus_frame_msgs = [m for m in sent if isinstance(m, BusFrameMessage)] self.assertEqual(len(bus_frame_msgs), 0) @@ -851,17 +851,17 @@ class TestJobLifecycle(unittest.IsolatedAsyncioTestCase): self.bus, self.tm = await create_test_bus() self.registry = create_test_registry() - async def _attach(self, task): - task.attach(registry=self.registry, bus=self.bus) - await task.setup(self.tm) - return task + async def _attach(self, worker): + worker.attach(registry=self.registry, bus=self.bus) + await worker.setup(self.tm) + return worker async def test_request_job_sends_request(self): - """request_job() sends BusJobRequestMessage to each task.""" + """request_job() sends BusJobRequestMessage to each worker.""" sent = capture_bus(self.bus) - parent = await self._attach(BaseTask("parent")) - await self.registry.register(TaskReadyData(task_name="worker", runner="test-runner")) + parent = await self._attach(BaseWorker("parent")) + await self.registry.register(WorkerReadyData(worker_name="worker", runner="test-runner")) job_id = await parent.request_job("worker", payload={"key": "val"}) @@ -875,7 +875,7 @@ class TestJobLifecycle(unittest.IsolatedAsyncioTestCase): """request_job_group() with multiple tasks sends messages for each.""" sent = capture_bus(self.bus) - parent = await self._attach(BaseTask("parent")) + parent = await self._attach(BaseWorker("parent")) await register_tasks(self.registry, "w1", "w2") job_id = await parent.request_job_group("w1", "w2", payload={"work": True}) @@ -889,15 +889,15 @@ class TestJobLifecycle(unittest.IsolatedAsyncioTestCase): async def test_on_job_request_called(self): """BusJobRequestMessage triggers on_job_request with the message.""" - task = await self._attach(BaseTask("worker")) + worker = await self._attach(BaseWorker("worker")) received = [] - @task.event_handler("on_job_request") + @worker.event_handler("on_job_request") async def on_request(t, message): received.append(message) - await task.on_bus_message( + await worker.on_bus_message( BusJobRequestMessage(source="parent", target="worker", job_id="t1", payload={"x": 1}) ) await asyncio.sleep(0) # let async event handlers run @@ -906,19 +906,19 @@ class TestJobLifecycle(unittest.IsolatedAsyncioTestCase): self.assertEqual(received[0].job_id, "t1") self.assertEqual(received[0].source, "parent") self.assertEqual(received[0].payload, {"x": 1}) - self.assertIn("t1", task.active_jobs) + self.assertIn("t1", worker.active_jobs) async def test_send_job_response(self): """send_job_response() sends BusJobResponseMessage to requester.""" sent = capture_bus(self.bus) - task = await self._attach(BaseTask("worker")) + worker = await self._attach(BaseWorker("worker")) # Simulate receiving a job request - await task.on_bus_message( + await worker.on_bus_message( BusJobRequestMessage(source="parent", target="worker", job_id="t1") ) - await task.send_job_response("t1", {"result": 42}) + await worker.send_job_response("t1", {"result": 42}) response_msgs = [m for m in sent if isinstance(m, BusJobResponseMessage)] self.assertEqual(len(response_msgs), 1) @@ -931,12 +931,12 @@ class TestJobLifecycle(unittest.IsolatedAsyncioTestCase): """send_job_update() sends BusJobUpdateMessage to requester.""" sent = capture_bus(self.bus) - task = await self._attach(BaseTask("worker")) - await task.on_bus_message( + worker = await self._attach(BaseWorker("worker")) + await worker.on_bus_message( BusJobRequestMessage(source="parent", target="worker", job_id="t1") ) - await task.send_job_update("t1", {"progress": 50}) + await worker.send_job_update("t1", {"progress": 50}) update_msgs = [m for m in sent if isinstance(m, BusJobUpdateMessage)] self.assertEqual(len(update_msgs), 1) @@ -946,7 +946,7 @@ class TestJobLifecycle(unittest.IsolatedAsyncioTestCase): async def test_on_job_completed_fires_when_all_respond(self): """on_job_completed fires when all tasks in a job group respond.""" - parent = await self._attach(BaseTask("parent")) + parent = await self._attach(BaseWorker("parent")) await register_tasks(self.registry, "w1", "w2") completed = [] @@ -989,7 +989,7 @@ class TestJobLifecycle(unittest.IsolatedAsyncioTestCase): """cancel_job_group() sends BusJobCancelMessage to all tasks in group.""" sent = capture_bus(self.bus) - parent = await self._attach(BaseTask("parent")) + parent = await self._attach(BaseWorker("parent")) await register_tasks(self.registry, "w1", "w2") job_id = await parent.request_job_group("w1", "w2") @@ -1007,50 +1007,50 @@ class TestJobLifecycle(unittest.IsolatedAsyncioTestCase): async def test_send_job_response_raises_without_active_job(self): """send_job_response raises RuntimeError when job_id is unknown.""" - task = await self._attach(BaseTask("worker")) + worker = await self._attach(BaseWorker("worker")) with self.assertRaises(RuntimeError): - await task.send_job_response("unknown", {"result": 1}) + await worker.send_job_response("unknown", {"result": 1}) async def test_send_job_update_raises_without_active_job(self): """send_job_update raises RuntimeError when job_id is unknown.""" - task = await self._attach(BaseTask("worker")) + worker = await self._attach(BaseWorker("worker")) with self.assertRaises(RuntimeError): - await task.send_job_update("unknown", {"progress": 50}) + await worker.send_job_update("unknown", {"progress": 50}) async def test_cancel_auto_sends_cancelled_response(self): """BusJobCancelMessage auto-sends a cancelled response and clears state.""" - task = await self._attach(BaseTask("worker")) + worker = await self._attach(BaseWorker("worker")) # Set up job state - await task.on_bus_message( + await worker.on_bus_message( BusJobRequestMessage(source="parent", target="worker", job_id="t1") ) - self.assertIn("t1", task.active_jobs) + self.assertIn("t1", worker.active_jobs) # Cancel should auto-send response (via send_job_response) and clear state - await task.on_bus_message( + await worker.on_bus_message( BusJobCancelMessage(source="parent", target="worker", job_id="t1") ) # Yield to let the cancel coroutine complete its work. await asyncio.sleep(0.05) - self.assertNotIn("t1", task.active_jobs) + self.assertNotIn("t1", worker.active_jobs) async def test_on_job_cancelled_fires(self): """BusJobCancelMessage triggers on_job_cancelled with the message.""" - task = await self._attach(BaseTask("worker")) + worker = await self._attach(BaseWorker("worker")) received = [] - @task.event_handler("on_job_cancelled") + @worker.event_handler("on_job_cancelled") async def on_cancelled(t, message): received.append(message) - await task.on_bus_message( + await worker.on_bus_message( BusJobRequestMessage(source="parent", target="worker", job_id="t1") ) - await task.on_bus_message( + await worker.on_bus_message( BusJobCancelMessage( source="parent", target="worker", job_id="t1", reason="no longer needed" ) @@ -1065,12 +1065,12 @@ class TestJobLifecycle(unittest.IsolatedAsyncioTestCase): """send_job_stream_start() sends BusJobStreamStartMessage to requester.""" sent = capture_bus(self.bus) - task = await self._attach(BaseTask("worker")) - await task.on_bus_message( + worker = await self._attach(BaseWorker("worker")) + await worker.on_bus_message( BusJobRequestMessage(source="parent", target="worker", job_id="t1") ) - await task.send_job_stream_start("t1", {"content_type": "text"}) + await worker.send_job_stream_start("t1", {"content_type": "text"}) msgs = [m for m in sent if isinstance(m, BusJobStreamStartMessage)] self.assertEqual(len(msgs), 1) @@ -1082,12 +1082,12 @@ class TestJobLifecycle(unittest.IsolatedAsyncioTestCase): """send_job_stream_data() sends BusJobStreamDataMessage to requester.""" sent = capture_bus(self.bus) - task = await self._attach(BaseTask("worker")) - await task.on_bus_message( + worker = await self._attach(BaseWorker("worker")) + await worker.on_bus_message( BusJobRequestMessage(source="parent", target="worker", job_id="t1") ) - await task.send_job_stream_data("t1", {"text": "hello "}) + await worker.send_job_stream_data("t1", {"text": "hello "}) msgs = [m for m in sent if isinstance(m, BusJobStreamDataMessage)] self.assertEqual(len(msgs), 1) @@ -1099,12 +1099,12 @@ class TestJobLifecycle(unittest.IsolatedAsyncioTestCase): """send_job_stream_end() sends BusJobStreamEndMessage to requester.""" sent = capture_bus(self.bus) - task = await self._attach(BaseTask("worker")) - await task.on_bus_message( + worker = await self._attach(BaseWorker("worker")) + await worker.on_bus_message( BusJobRequestMessage(source="parent", target="worker", job_id="t1") ) - await task.send_job_stream_end("t1", {"final": True}) + await worker.send_job_stream_end("t1", {"final": True}) msgs = [m for m in sent if isinstance(m, BusJobStreamEndMessage)] self.assertEqual(len(msgs), 1) @@ -1114,7 +1114,7 @@ class TestJobLifecycle(unittest.IsolatedAsyncioTestCase): async def test_stream_end_triggers_on_job_completed(self): """BusJobStreamEndMessage triggers group completion like BusJobResponseMessage.""" - parent = await self._attach(BaseTask("parent")) + parent = await self._attach(BaseWorker("parent")) await register_tasks(self.registry, "w1", "w2") completed = [] @@ -1125,7 +1125,7 @@ class TestJobLifecycle(unittest.IsolatedAsyncioTestCase): job_id = await parent.request_job_group("w1", "w2") - # First task ends stream — should not trigger on_job_completed + # First worker ends stream — should not trigger on_job_completed await parent.on_bus_message( BusJobStreamEndMessage( source="w1", target="parent", job_id=job_id, data={"result": "a"} @@ -1134,7 +1134,7 @@ class TestJobLifecycle(unittest.IsolatedAsyncioTestCase): await asyncio.sleep(0) self.assertEqual(len(completed), 0) - # Second task ends stream — should trigger on_job_completed + # Second worker ends stream — should trigger on_job_completed await parent.on_bus_message( BusJobStreamEndMessage( source="w2", target="parent", job_id=job_id, data={"result": "b"} @@ -1147,22 +1147,22 @@ class TestJobLifecycle(unittest.IsolatedAsyncioTestCase): async def test_send_job_stream_raises_without_active_job(self): """All stream helpers raise RuntimeError when job_id is unknown.""" - task = await self._attach(BaseTask("worker")) + worker = await self._attach(BaseWorker("worker")) with self.assertRaises(RuntimeError): - await task.send_job_stream_start("unknown") + await worker.send_job_stream_start("unknown") with self.assertRaises(RuntimeError): - await task.send_job_stream_data("unknown") + await worker.send_job_stream_data("unknown") with self.assertRaises(RuntimeError): - await task.send_job_stream_end("unknown") + await worker.send_job_stream_end("unknown") async def test_request_job_timeout_cancels_job(self): """Short timeout triggers BusJobCancelMessage with reason 'timeout'.""" sent = capture_bus(self.bus) - parent = await self._attach(BaseTask("parent")) + parent = await self._attach(BaseWorker("parent")) await register_tasks(self.registry, "worker") job_id = await parent.request_job("worker", timeout=0.05) @@ -1182,12 +1182,12 @@ class TestJobLifecycle(unittest.IsolatedAsyncioTestCase): """Responding before timeout prevents cancel from being sent.""" sent = capture_bus(self.bus) - parent = await self._attach(BaseTask("parent")) + parent = await self._attach(BaseWorker("parent")) await register_tasks(self.registry, "worker") job_id = await parent.request_job("worker", timeout=0.5) - # Let the timeout task start before responding + # Let the timeout worker start before responding await asyncio.sleep(0) # Respond before timeout fires @@ -1212,7 +1212,7 @@ class TestJobLifecycle(unittest.IsolatedAsyncioTestCase): async def test_request_job_no_timeout_by_default(self): """timeout_task is None when no timeout is given.""" - parent = await self._attach(BaseTask("parent")) + parent = await self._attach(BaseWorker("parent")) await register_tasks(self.registry, "worker") job_id = await parent.request_job("worker") @@ -1226,10 +1226,10 @@ class TestJobDecorator(unittest.IsolatedAsyncioTestCase): self.bus, self.tm = await create_test_bus() self.registry = create_test_registry() - async def _attach(self, task): - task.attach(registry=self.registry, bus=self.bus) - await task.setup(self.tm) - return task + async def _attach(self, worker): + worker.attach(registry=self.registry, bus=self.bus) + await worker.setup(self.tm) + return worker async def _wait_until(self, predicate, timeout=1.0): deadline = asyncio.get_event_loop().time() + timeout @@ -1245,7 +1245,7 @@ class TestJobDecorator(unittest.IsolatedAsyncioTestCase): completion_order: list[str] = [] gates: dict[str, asyncio.Event] = {} - class WorkerTask(BaseTask): + class WorkerTask(BaseWorker): @job(name="work", sequential=True) async def on_work(self, message): nonlocal running, max_running @@ -1255,11 +1255,11 @@ class TestJobDecorator(unittest.IsolatedAsyncioTestCase): completion_order.append(message.job_id) running -= 1 - task = await self._attach(WorkerTask("worker")) + worker = await self._attach(WorkerTask("worker")) for tid in ("t1", "t2", "t3"): gates[tid] = asyncio.Event() - await task.on_bus_message( + await worker.on_bus_message( BusJobRequestMessage(source="parent", target="worker", job_id=tid, job_name="work") ) @@ -1280,7 +1280,7 @@ class TestJobDecorator(unittest.IsolatedAsyncioTestCase): max_running = 0 release = asyncio.Event() - class WorkerTask(BaseTask): + class WorkerTask(BaseWorker): @job(name="work") async def on_work(self, message): nonlocal running, max_running @@ -1289,10 +1289,10 @@ class TestJobDecorator(unittest.IsolatedAsyncioTestCase): await release.wait() running -= 1 - task = await self._attach(WorkerTask("worker")) + worker = await self._attach(WorkerTask("worker")) for tid in ("t1", "t2"): - await task.on_bus_message( + await worker.on_bus_message( BusJobRequestMessage(source="parent", target="worker", job_id=tid, job_name="work") ) @@ -1307,7 +1307,7 @@ class TestJobDecorator(unittest.IsolatedAsyncioTestCase): max_running = 0 release = asyncio.Event() - class WorkerTask(BaseTask): + class WorkerTask(BaseWorker): @job(name="a", sequential=True) async def on_a(self, message): nonlocal running, max_running @@ -1324,12 +1324,12 @@ class TestJobDecorator(unittest.IsolatedAsyncioTestCase): await release.wait() running -= 1 - task = await self._attach(WorkerTask("worker")) + worker = await self._attach(WorkerTask("worker")) - await task.on_bus_message( + await worker.on_bus_message( BusJobRequestMessage(source="parent", target="worker", job_id="ta", job_name="a") ) - await task.on_bus_message( + await worker.on_bus_message( BusJobRequestMessage(source="parent", target="worker", job_id="tb", job_name="b") ) diff --git a/tests/test_bridge_processor.py b/tests/test_bridge_processor.py index 92f611cb5..5279412a4 100644 --- a/tests/test_bridge_processor.py +++ b/tests/test_bridge_processor.py @@ -29,7 +29,7 @@ class TestBusBridgeProcessor(unittest.IsolatedAsyncioTestCase): processor = BusBridgeProcessor( bus=bus, - task_name="test_task", + worker_name="test_task", ) pipeline = Pipeline([processor]) @@ -66,7 +66,7 @@ class TestBusBridgeProcessor(unittest.IsolatedAsyncioTestCase): processor = BusBridgeProcessor( bus=bus, - task_name="test_task", + worker_name="test_task", ) pipeline = Pipeline([processor]) @@ -98,7 +98,7 @@ class TestBusBridgeProcessor(unittest.IsolatedAsyncioTestCase): processor = BusBridgeProcessor( bus=bus, - task_name="test_task", + worker_name="test_task", exclude_frames=(TextFrame,), ) pipeline = Pipeline([processor]) @@ -125,7 +125,7 @@ class TestBusBridgeProcessor(unittest.IsolatedAsyncioTestCase): travel downstream alongside frames from later pipeline processors.""" from pipecat.frames.frames import EndFrame from pipecat.pipeline.runner import PipelineRunner - from pipecat.pipeline.task import PipelineTask + from pipecat.pipeline.worker import PipelineWorker from pipecat.processors.frame_processor import FrameProcessor class AppendFrameProcessor(FrameProcessor): @@ -140,16 +140,16 @@ class TestBusBridgeProcessor(unittest.IsolatedAsyncioTestCase): bus = AsyncQueueBus() bridge = BusBridgeProcessor( bus=bus, - task_name="main_task", + worker_name="main_task", ) pipeline = Pipeline([bridge, AppendFrameProcessor()]) - task = PipelineTask(pipeline, cancel_on_idle_timeout=False) + worker = PipelineWorker(pipeline, cancel_on_idle_timeout=False) received = [] - task.set_reached_downstream_filter((TextFrame,)) + worker.set_reached_downstream_filter((TextFrame,)) - @task.event_handler("on_frame_reached_downstream") - async def on_frame(task, frame): + @worker.event_handler("on_frame_reached_downstream") + async def on_frame(worker, frame): received.append(frame) msg = BusFrameMessage( @@ -162,21 +162,21 @@ class TestBusBridgeProcessor(unittest.IsolatedAsyncioTestCase): await asyncio.sleep(0.02) await bridge.on_bus_message(msg) await asyncio.sleep(0.02) - await task.queue_frame(EndFrame()) + await worker.queue_frame(EndFrame()) runner = PipelineRunner() - await asyncio.gather(runner.run(task), inject_and_end()) + await asyncio.gather(runner.run(worker), inject_and_end()) texts = [f.text for f in received if isinstance(f, TextFrame)] self.assertIn("from_child", texts) self.assertIn("after_bridge", texts) async def test_skips_own_frames(self): - """Bridge ignores bus frames from its own task.""" + """Bridge ignores bus frames from its own worker.""" bus = AsyncQueueBus() processor = BusBridgeProcessor( bus=bus, - task_name="test_task", + worker_name="test_task", ) injected = [] @@ -200,11 +200,11 @@ class TestBusBridgeProcessor(unittest.IsolatedAsyncioTestCase): self.assertEqual(len(injected), 0) async def test_target_task_filtering(self): - """Bridge with target_task only accepts frames from that task.""" + """Bridge with target_task only accepts frames from that worker.""" bus = AsyncQueueBus() processor = BusBridgeProcessor( bus=bus, - task_name="main_task", + worker_name="main_task", target_task="specific_child", ) @@ -217,7 +217,7 @@ class TestBusBridgeProcessor(unittest.IsolatedAsyncioTestCase): processor.push_frame = capture_push - # Frame from wrong task — should be ignored + # Frame from wrong worker — should be ignored wrong_msg = BusFrameMessage( source="other_child", frame=TextFrame(text="wrong"), @@ -226,7 +226,7 @@ class TestBusBridgeProcessor(unittest.IsolatedAsyncioTestCase): await processor.on_bus_message(wrong_msg) self.assertEqual(len(injected), 0) - # Frame from correct task — should be injected + # Frame from correct worker — should be injected right_msg = BusFrameMessage( source="specific_child", frame=TextFrame(text="right"), @@ -237,11 +237,11 @@ class TestBusBridgeProcessor(unittest.IsolatedAsyncioTestCase): self.assertEqual(injected[0].text, "right") async def test_targeted_message_for_other_task_skipped(self): - """Bridge skips bus messages targeted at a different task.""" + """Bridge skips bus messages targeted at a different worker.""" bus = AsyncQueueBus() processor = BusBridgeProcessor( bus=bus, - task_name="main_task", + worker_name="main_task", ) injected = [] diff --git a/tests/test_bus.py b/tests/test_bus.py index e6bac7be7..8e9512e00 100644 --- a/tests/test_bus.py +++ b/tests/test_bus.py @@ -11,7 +11,7 @@ import unittest from pipecat.bus import ( AsyncQueueBus, BusCancelMessage, - BusCancelTaskMessage, + BusCancelWorkerMessage, BusDataMessage, BusJobCancelMessage, BusSubscriber, @@ -245,7 +245,7 @@ class TestBusMessagePriority(unittest.IsolatedAsyncioTestCase): await bus.send(BusDataMessage(source="data_2")) await bus.send(BusCancelMessage(source="cancel_1")) await bus.send(BusDataMessage(source="data_3")) - await bus.send(BusCancelTaskMessage(source="cancel_2", target="task")) + await bus.send(BusCancelWorkerMessage(source="cancel_2", target="task")) await bus.start() await asyncio.sleep(0.1) diff --git a/tests/test_job_group.py b/tests/test_job_group.py index 210bb63d5..c1cd76785 100644 --- a/tests/test_job_group.py +++ b/tests/test_job_group.py @@ -13,7 +13,7 @@ from pipecat.bus import ( BusJobRequestMessage, BusJobResponseMessage, ) -from pipecat.pipeline.base_task import BaseTask +from pipecat.pipeline.base_worker import BaseWorker from pipecat.pipeline.job_context import ( JobError, JobEvent, @@ -21,16 +21,16 @@ from pipecat.pipeline.job_context import ( JobGroupEvent, JobStatus, ) -from pipecat.registry import TaskRegistry -from pipecat.registry.types import TaskReadyData +from pipecat.registry import WorkerRegistry +from pipecat.registry.types import WorkerReadyData from pipecat.utils.asyncio.task_manager import TaskManager, TaskManagerParams -class StubTask(BaseTask): +class StubTask(BaseWorker): pass -class JobWorkerTask(BaseTask): +class JobWorkerTask(BaseWorker): """Worker that automatically responds to job requests via the bus.""" def __init__(self, name, *, response=None, status=JobStatus.COMPLETED): @@ -43,7 +43,7 @@ class JobWorkerTask(BaseTask): await self.send_job_response(message.job_id, self._auto_response, status=self._auto_status) -class UrgentJobWorkerTask(BaseTask): +class UrgentJobWorkerTask(BaseWorker): """Worker that responds urgently to job requests.""" def __init__(self, name, *, response=None, status=JobStatus.COMPLETED): @@ -58,7 +58,7 @@ class UrgentJobWorkerTask(BaseTask): ) -class UpdatingWorkerTask(BaseTask): +class UpdatingWorkerTask(BaseWorker): """Worker that sends updates before responding.""" def __init__(self, name, *, updates, response=None): @@ -73,7 +73,7 @@ class UpdatingWorkerTask(BaseTask): await self.send_job_response(message.job_id, self._auto_response) -class StreamingWorkerTask(BaseTask): +class StreamingWorkerTask(BaseWorker): """Worker that streams data before responding.""" def __init__(self, name, *, chunks, response=None): @@ -89,7 +89,7 @@ class StreamingWorkerTask(BaseTask): await self.send_job_stream_end(message.job_id, self._auto_response) -class SlowWorkerTask(BaseTask): +class SlowWorkerTask(BaseWorker): """Worker that blocks during job execution until cancelled.""" def __init__(self, name): @@ -113,7 +113,7 @@ async def create_test_env(): tm.setup(TaskManagerParams(loop=asyncio.get_running_loop())) await bus.setup(tm) await bus.start() - registry = TaskRegistry(runner_name="test-runner") + registry = WorkerRegistry(runner_name="test-runner") return bus, tm, registry @@ -122,7 +122,7 @@ async def setup_task(bus, registry, task): task.attach(registry=registry, bus=bus) await task.setup(bus.task_manager) await bus.subscribe(task) - await registry.register(TaskReadyData(task_name=task.name, runner="test-runner")) + await registry.register(WorkerReadyData(worker_name=task.name, runner="test-runner")) def capture_bus(bus): @@ -351,7 +351,7 @@ class TestJobGroupContext(unittest.IsolatedAsyncioTestCase): self.assertEqual(len(events), 2) self.assertEqual(events[0].type, JobGroupEvent.UPDATE) - self.assertEqual(events[0].task_name, "worker") + self.assertEqual(events[0].worker_name, "worker") self.assertEqual(events[0].data, {"progress": 25}) self.assertEqual(events[1].data, {"progress": 75}) self.assertEqual(tg.responses, {"worker": {"result": "done"}}) @@ -405,7 +405,7 @@ class TestJobGroupContext(unittest.IsolatedAsyncioTestCase): self.assertEqual(len(events), 1) self.assertEqual(events[0].type, JobGroupEvent.UPDATE) - self.assertEqual(events[0].task_name, "w1") + self.assertEqual(events[0].worker_name, "w1") self.assertEqual(tg.responses, {"w1": {"a": 1}, "w2": {"b": 2}}) async def test_job_group_no_iteration_still_works(self): diff --git a/tests/test_llm_service.py b/tests/test_llm_service.py index f51c5e3c2..f084b0753 100644 --- a/tests/test_llm_service.py +++ b/tests/test_llm_service.py @@ -47,7 +47,7 @@ class MockLLMService(LLMService): ) super().__init__(settings=settings, **kwargs) # Stub the pipeline task so FunctionCallParams can be constructed. - self._pipeline_task = SimpleNamespace(app_resources=None) + self._pipeline_worker = SimpleNamespace(app_resources=None) class TestUnparameterizedSubclass(unittest.TestCase): diff --git a/tests/test_llm_task.py b/tests/test_llm_worker.py similarity index 95% rename from tests/test_llm_task.py rename to tests/test_llm_worker.py index 6e59cefb1..a5f2abeb1 100644 --- a/tests/test_llm_task.py +++ b/tests/test_llm_worker.py @@ -9,16 +9,16 @@ import unittest from unittest.mock import MagicMock from pipecat.frames.frames import LLMMessagesAppendFrame -from pipecat.pipeline.task import PipelineTask +from pipecat.pipeline.worker import PipelineWorker from pipecat.processors.frame_processor import FrameDirection -from pipecat.tasks.llm import LLMTask, tool -from pipecat.tasks.llm.llm_task import PipelineFlushFrame +from pipecat.workers.llm import LLMWorker, tool +from pipecat.workers.llm.llm_worker import PipelineFlushFrame def _create_task(): """Create a StubLLMTask with mocked parent queue_frame for testing.""" - class StubLLMTask(LLMTask): + class StubLLMTask(LLMWorker): @tool async def fast_tool(self, params): """A quick tool.""" @@ -33,11 +33,11 @@ def _create_task(): llm.register_direct_function = MagicMock() task = StubLLMTask("test_task", llm=llm, bridged=()) - # Capture frames passed to PipelineTask.queue_frame (i.e. super().queue_frame). + # Capture frames passed to PipelineWorker.queue_frame (i.e. super().queue_frame). # Auto-set _flush_done when PipelineFlushFrame is queued, simulating the flush # round-trip through the pipeline. delivered: list[tuple] = [] - original_pt_queue_frame = PipelineTask.queue_frame + original_pt_queue_frame = PipelineWorker.queue_frame async def class_replacement(self, frame, direction=FrameDirection.DOWNSTREAM): # Only intercept for this specific instance; otherwise fall through. @@ -48,9 +48,9 @@ def _create_task(): return await original_pt_queue_frame(self, frame, direction) - PipelineTask.queue_frame = class_replacement + PipelineWorker.queue_frame = class_replacement task._restore_pt_queue_frame = lambda: setattr( - PipelineTask, "queue_frame", original_pt_queue_frame + PipelineWorker, "queue_frame", original_pt_queue_frame ) task._delivered_frames = delivered diff --git a/tests/test_pgmq_bus.py b/tests/test_pgmq_bus.py index b93defe4d..fc9f417cf 100644 --- a/tests/test_pgmq_bus.py +++ b/tests/test_pgmq_bus.py @@ -12,7 +12,7 @@ from dataclasses import dataclass, field from datetime import datetime from pipecat.bus import ( - BusAddTaskMessage, + BusAddWorkerMessage, BusDataMessage, BusEndMessage, BusFrameMessage, @@ -21,7 +21,7 @@ from pipecat.bus import ( ) from pipecat.bus.serializers import JSONMessageSerializer from pipecat.frames.frames import TextFrame -from pipecat.pipeline.base_task import BaseTask +from pipecat.pipeline.base_worker import BaseWorker from pipecat.processors.frame_processor import FrameDirection from pipecat.utils.asyncio.task_manager import TaskManager, TaskManagerParams @@ -171,8 +171,8 @@ class TestPgmqBus(unittest.IsolatedAsyncioTestCase): received = [] await self.bus.subscribe(_make_sub(received)) - task = BaseTask("test") - msg = BusAddTaskMessage(source="parent", task=task) + worker = BaseWorker("test") + msg = BusAddWorkerMessage(source="parent", worker=worker) await self.bus.send(msg) await asyncio.sleep(0.05) @@ -181,8 +181,8 @@ class TestPgmqBus(unittest.IsolatedAsyncioTestCase): self.assertEqual(len(self.pgmq.sent), 0) # But delivered locally self.assertEqual(len(received), 1) - self.assertIsInstance(received[0], BusAddTaskMessage) - self.assertIs(received[0].task, task) + self.assertIsInstance(received[0], BusAddWorkerMessage) + self.assertIs(received[0].worker, worker) async def test_round_trip_via_subscriber(self): """Messages published are received by subscribers.""" @@ -367,7 +367,7 @@ class TestPgmqBusEdgeCases(unittest.IsolatedAsyncioTestCase): await bus.stop() async def test_stop_cleans_up(self): - """stop() cancels the reader task and drops the queue.""" + """stop() cancels the reader worker and drops the queue.""" pgmq = FakePgmq() bus = PgmqBus(pgmq=pgmq, channel="cleanup_test", poll_interval_ms=10, max_poll_seconds=1) tm = TaskManager() diff --git a/tests/test_pipeline.py b/tests/test_pipeline.py index b260fc2c8..c635fc71e 100644 --- a/tests/test_pipeline.py +++ b/tests/test_pipeline.py @@ -25,7 +25,7 @@ from pipecat.frames.frames import ( from pipecat.observers.base_observer import BaseObserver, FramePushed from pipecat.pipeline.parallel_pipeline import ParallelPipeline from pipecat.pipeline.pipeline import Pipeline -from pipecat.pipeline.task import PipelineParams, PipelineTask, PipelineTaskParams +from pipecat.pipeline.worker import PipelineParams, PipelineWorker, PipelineWorkerParams from pipecat.processors.filters.frame_filter import FrameFilter from pipecat.processors.filters.identity_filter import IdentityFilter from pipecat.processors.frame_processor import FrameDirection, FrameProcessor @@ -130,12 +130,12 @@ class TestParallelPipeline(unittest.IsolatedAsyncioTestCase): class TestPipelineTask(unittest.IsolatedAsyncioTestCase): async def test_task_single(self): pipeline = Pipeline([IdentityFilter()]) - task = PipelineTask(pipeline) + worker = PipelineWorker(pipeline) - await task.queue_frame(TextFrame(text="Hello!")) - await task.queue_frames([TextFrame(text="Bye!"), EndFrame()]) - await task.run(PipelineTaskParams(loop=asyncio.get_event_loop())) - assert task.has_finished() + await worker.queue_frame(TextFrame(text="Hello!")) + await worker.queue_frames([TextFrame(text="Bye!"), EndFrame()]) + await worker.run(PipelineWorkerParams(loop=asyncio.get_event_loop())) + assert worker.has_finished() async def test_task_observers(self): frame_received = False @@ -149,10 +149,10 @@ class TestPipelineTask(unittest.IsolatedAsyncioTestCase): identity = IdentityFilter() pipeline = Pipeline([identity]) - task = PipelineTask(pipeline, observers=[CustomObserver()]) + worker = PipelineWorker(pipeline, observers=[CustomObserver()]) - await task.queue_frames([TextFrame(text="Hello Downstream!"), EndFrame()]) - await task.run(PipelineTaskParams(loop=asyncio.get_event_loop())) + await worker.queue_frames([TextFrame(text="Hello Downstream!"), EndFrame()]) + await worker.run(PipelineWorkerParams(loop=asyncio.get_event_loop())) assert frame_received async def test_task_add_observer(self): @@ -183,32 +183,32 @@ class TestPipelineTask(unittest.IsolatedAsyncioTestCase): identity = IdentityFilter() pipeline = Pipeline([identity]) - task = PipelineTask(pipeline, observers=[CustomObserver()]) + worker = PipelineWorker(pipeline, observers=[CustomObserver()]) - # Add a new observer right away, before doing anything else with the task. + # Add a new observer right away, before doing anything else with the worker. observer1 = CustomAddObserver1() - task.add_observer(observer1) + worker.add_observer(observer1) async def delayed_add_observer(): observer2 = CustomAddObserver2() # Wait after the pipeline is started and add another observer. await asyncio.sleep(0.1) - task.add_observer(observer2) + worker.add_observer(observer2) # Push a TextFrame and wait for the observer to pick it up. - await task.queue_frame(TextFrame(text="Hello Downstream!")) + await worker.queue_frame(TextFrame(text="Hello Downstream!")) await asyncio.sleep(0.1) # Remove both observers. - await task.remove_observer(observer1) - await task.remove_observer(observer2) + await worker.remove_observer(observer1) + await worker.remove_observer(observer2) # Push another TextFrame. This time the counter should not # increments since we have removed the observer. - await task.queue_frame(TextFrame(text="Hello Downstream!")) + await worker.queue_frame(TextFrame(text="Hello Downstream!")) await asyncio.sleep(0.1) # Finally end the pipeline. - await task.queue_frame(EndFrame()) + await worker.queue_frame(EndFrame()) await asyncio.gather( - task.run(PipelineTaskParams(loop=asyncio.get_event_loop())), delayed_add_observer() + worker.run(PipelineWorkerParams(loop=asyncio.get_event_loop())), delayed_add_observer() ) assert frame_received @@ -221,20 +221,20 @@ class TestPipelineTask(unittest.IsolatedAsyncioTestCase): identity = IdentityFilter() pipeline = Pipeline([identity]) - task = PipelineTask(pipeline) + worker = PipelineWorker(pipeline) - @task.event_handler("on_pipeline_started") - async def on_pipeline_started(task, frame: StartFrame): + @worker.event_handler("on_pipeline_started") + async def on_pipeline_started(worker, frame: StartFrame): nonlocal start_received start_received = True - @task.event_handler("on_pipeline_finished") - async def on_pipeline_finished(task, frame: Frame): + @worker.event_handler("on_pipeline_finished") + async def on_pipeline_finished(worker, frame: Frame): nonlocal end_received end_received = isinstance(frame, EndFrame) - await task.queue_frame(EndFrame()) - await task.run(PipelineTaskParams(loop=asyncio.get_event_loop())) + await worker.queue_frame(EndFrame()) + await worker.run(PipelineWorkerParams(loop=asyncio.get_event_loop())) assert start_received assert end_received @@ -244,15 +244,15 @@ class TestPipelineTask(unittest.IsolatedAsyncioTestCase): identity = IdentityFilter() pipeline = Pipeline([identity]) - task = PipelineTask(pipeline) + worker = PipelineWorker(pipeline) - @task.event_handler("on_pipeline_finished") - async def on_pipeline_finished(task, frame: Frame): + @worker.event_handler("on_pipeline_finished") + async def on_pipeline_finished(worker, frame: Frame): nonlocal stop_received stop_received = isinstance(frame, StopFrame) - await task.queue_frame(StopFrame()) - await task.run(PipelineTaskParams(loop=asyncio.get_event_loop())) + await worker.queue_frame(StopFrame()) + await worker.run(PipelineWorkerParams(loop=asyncio.get_event_loop())) assert stop_received @@ -262,18 +262,18 @@ class TestPipelineTask(unittest.IsolatedAsyncioTestCase): identity = IdentityFilter() pipeline = Pipeline([identity]) - task = PipelineTask(pipeline, cancel_on_idle_timeout=False) - task.set_reached_upstream_filter((TextFrame,)) - task.set_reached_downstream_filter((TextFrame,)) + worker = PipelineWorker(pipeline, cancel_on_idle_timeout=False) + worker.set_reached_upstream_filter((TextFrame,)) + worker.set_reached_downstream_filter((TextFrame,)) - @task.event_handler("on_frame_reached_upstream") - async def on_frame_reached_upstream(task, frame): + @worker.event_handler("on_frame_reached_upstream") + async def on_frame_reached_upstream(worker, frame): nonlocal upstream_received if isinstance(frame, TextFrame) and frame.text == "Hello Upstream!": upstream_received = True - @task.event_handler("on_frame_reached_downstream") - async def on_frame_reached_downstream(task, frame): + @worker.event_handler("on_frame_reached_downstream") + async def on_frame_reached_downstream(worker, frame): nonlocal downstream_received if isinstance(frame, TextFrame) and frame.text == "Hello Downstream!": downstream_received = True @@ -281,11 +281,11 @@ class TestPipelineTask(unittest.IsolatedAsyncioTestCase): TextFrame(text="Hello Upstream!"), FrameDirection.UPSTREAM ) - await task.queue_frame(TextFrame(text="Hello Downstream!")) + await worker.queue_frame(TextFrame(text="Hello Downstream!")) try: await asyncio.wait_for( - task.run(PipelineTaskParams(loop=asyncio.get_event_loop())), + worker.run(PipelineWorkerParams(loop=asyncio.get_event_loop())), timeout=1.0, ) except TimeoutError: @@ -298,22 +298,22 @@ class TestPipelineTask(unittest.IsolatedAsyncioTestCase): upstream_received = False pipeline = Pipeline([IdentityFilter()]) - task = PipelineTask(pipeline, cancel_on_idle_timeout=False) - task.set_reached_upstream_filter((TextFrame,)) + worker = PipelineWorker(pipeline, cancel_on_idle_timeout=False) + worker.set_reached_upstream_filter((TextFrame,)) - @task.event_handler("on_frame_reached_upstream") - async def on_frame_reached_upstream(task, frame): + @worker.event_handler("on_frame_reached_upstream") + async def on_frame_reached_upstream(worker, frame): nonlocal upstream_received if isinstance(frame, TextFrame) and frame.text == "Hello Upstream!": upstream_received = True - @task.event_handler("on_pipeline_started") - async def on_pipeline_started(task, frame): - await task.queue_frame(TextFrame(text="Hello Upstream!"), FrameDirection.UPSTREAM) + @worker.event_handler("on_pipeline_started") + async def on_pipeline_started(worker, frame): + await worker.queue_frame(TextFrame(text="Hello Upstream!"), FrameDirection.UPSTREAM) try: await asyncio.wait_for( - task.run(PipelineTaskParams(loop=asyncio.get_event_loop())), + worker.run(PipelineWorkerParams(loop=asyncio.get_event_loop())), timeout=1.0, ) except TimeoutError: @@ -325,24 +325,24 @@ class TestPipelineTask(unittest.IsolatedAsyncioTestCase): upstream_texts = [] pipeline = Pipeline([IdentityFilter()]) - task = PipelineTask(pipeline, cancel_on_idle_timeout=False) - task.set_reached_upstream_filter((TextFrame,)) + worker = PipelineWorker(pipeline, cancel_on_idle_timeout=False) + worker.set_reached_upstream_filter((TextFrame,)) - @task.event_handler("on_frame_reached_upstream") - async def on_frame_reached_upstream(task, frame): + @worker.event_handler("on_frame_reached_upstream") + async def on_frame_reached_upstream(worker, frame): if isinstance(frame, TextFrame): upstream_texts.append(frame.text) - @task.event_handler("on_pipeline_started") - async def on_pipeline_started(task, frame): - await task.queue_frames( + @worker.event_handler("on_pipeline_started") + async def on_pipeline_started(worker, frame): + await worker.queue_frames( [TextFrame(text="First"), TextFrame(text="Second")], FrameDirection.UPSTREAM, ) try: await asyncio.wait_for( - task.run(PipelineTaskParams(loop=asyncio.get_event_loop())), + worker.run(PipelineWorkerParams(loop=asyncio.get_event_loop())), timeout=1.0, ) except TimeoutError: @@ -363,7 +363,7 @@ class TestPipelineTask(unittest.IsolatedAsyncioTestCase): heartbeats_observer = HeartbeatsObserver( target=identity, heartbeat_callback=heartbeat_received ) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_heartbeats=True, @@ -375,10 +375,10 @@ class TestPipelineTask(unittest.IsolatedAsyncioTestCase): expected_heartbeats = 1.0 / 0.2 - await task.queue_frame(TextFrame(text="Hello!")) + await worker.queue_frame(TextFrame(text="Hello!")) try: await asyncio.wait_for( - task.run(PipelineTaskParams(loop=asyncio.get_event_loop())), + worker.run(PipelineWorkerParams(loop=asyncio.get_event_loop())), timeout=1.0, ) except TimeoutError: @@ -401,7 +401,7 @@ class TestPipelineTask(unittest.IsolatedAsyncioTestCase): try: pipeline = Pipeline([HeartbeatBlocker()]) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_heartbeats=True, @@ -413,7 +413,7 @@ class TestPipelineTask(unittest.IsolatedAsyncioTestCase): try: await asyncio.wait_for( - task.run(PipelineTaskParams(loop=asyncio.get_event_loop())), + worker.run(PipelineWorkerParams(loop=asyncio.get_event_loop())), timeout=0.6, ) except TimeoutError: @@ -427,17 +427,17 @@ class TestPipelineTask(unittest.IsolatedAsyncioTestCase): async def test_idle_task(self): identity = IdentityFilter() pipeline = Pipeline([identity]) - task = PipelineTask(pipeline, idle_timeout_secs=0.2) + worker = PipelineWorker(pipeline, idle_timeout_secs=0.2) # This shouldn't freeze, so nothing to check really. - await task.run(PipelineTaskParams(loop=asyncio.get_event_loop())) + await worker.run(PipelineWorkerParams(loop=asyncio.get_event_loop())) async def test_no_idle_task(self): identity = IdentityFilter() pipeline = Pipeline([identity]) - task = PipelineTask(pipeline, idle_timeout_secs=0.2, cancel_on_idle_timeout=False) + worker = PipelineWorker(pipeline, idle_timeout_secs=0.2, cancel_on_idle_timeout=False) try: await asyncio.wait_for( - task.run(PipelineTaskParams(loop=asyncio.get_event_loop())), + worker.run(PipelineWorkerParams(loop=asyncio.get_event_loop())), timeout=0.3, ) except TimeoutError: @@ -448,7 +448,7 @@ class TestPipelineTask(unittest.IsolatedAsyncioTestCase): async def test_idle_task_heartbeats(self): identity = IdentityFilter() pipeline = Pipeline([identity]) - task = PipelineTask( + worker = PipelineWorker( pipeline, params=PipelineParams( enable_heartbeats=True, @@ -456,39 +456,39 @@ class TestPipelineTask(unittest.IsolatedAsyncioTestCase): ), idle_timeout_secs=0.3, ) - await task.run(PipelineTaskParams(loop=asyncio.get_event_loop())) + await worker.run(PipelineWorkerParams(loop=asyncio.get_event_loop())) async def test_idle_task_event_handler_no_frames(self): identity = IdentityFilter() pipeline = Pipeline([identity]) - task = PipelineTask(pipeline, idle_timeout_secs=0.2, cancel_on_idle_timeout=False) + worker = PipelineWorker(pipeline, idle_timeout_secs=0.2, cancel_on_idle_timeout=False) idle_timeout = False - @task.event_handler("on_idle_timeout") - async def on_idle_timeout(task: PipelineTask): + @worker.event_handler("on_idle_timeout") + async def on_idle_timeout(worker: PipelineWorker): nonlocal idle_timeout idle_timeout = True - await task.cancel() + await worker.cancel() - await task.run(PipelineTaskParams(loop=asyncio.get_event_loop())) + await worker.run(PipelineWorkerParams(loop=asyncio.get_event_loop())) assert idle_timeout async def test_idle_task_event_handler_quiet_user(self): identity = IdentityFilter() pipeline = Pipeline([identity]) - task = PipelineTask(pipeline, idle_timeout_secs=0.2, cancel_on_idle_timeout=False) + worker = PipelineWorker(pipeline, idle_timeout_secs=0.2, cancel_on_idle_timeout=False) idle_timeout = 0 - @task.event_handler("on_idle_timeout") - async def on_idle_timeout(task: PipelineTask): + @worker.event_handler("on_idle_timeout") + async def on_idle_timeout(worker: PipelineWorker): nonlocal idle_timeout idle_timeout += 1 # Stay a bit longer here while user audio frames are still being # pushed. We do this to make sure this function is only called once. await asyncio.sleep(0.1) - await task.queue_frame(EndFrame()) + await worker.queue_frame(EndFrame()) async def send_audio(): # We send audio during and after the 0.2 seconds of idle @@ -496,13 +496,13 @@ class TestPipelineTask(unittest.IsolatedAsyncioTestCase): # simulating the pipeline finishing (e.g. goodbye message from bot # flushing). for i in range(30): - await task.queue_frame( + await worker.queue_frame( InputAudioRawFrame(audio=b"\x00", sample_rate=16000, num_channels=1) ) await asyncio.sleep(0.01) await asyncio.gather( - send_audio(), task.run(PipelineTaskParams(loop=asyncio.get_event_loop())) + send_audio(), worker.run(PipelineWorkerParams(loop=asyncio.get_event_loop())) ) assert idle_timeout == 1 @@ -513,7 +513,7 @@ class TestPipelineTask(unittest.IsolatedAsyncioTestCase): # Use the identify filter so the frames just reach the end of the pipeline. identity = IdentityFilter() pipeline = Pipeline([identity]) - task = PipelineTask( + worker = PipelineWorker( pipeline, idle_timeout_secs=idle_timeout_secs, idle_timeout_frames=(TextFrame,), @@ -523,20 +523,20 @@ class TestPipelineTask(unittest.IsolatedAsyncioTestCase): """Sending multiple text frames. The total amount of elapsed time in this function should be greater - than the task idle timeout. If an idle timeout event is triggered it + than the worker idle timeout. If an idle timeout event is triggered it means we haven't detected that the TextFrames have been pushed. """ await asyncio.sleep(sleep_time_secs) - await task.queue_frame(TextFrame("Hello Pipecat!")) + await worker.queue_frame(TextFrame("Hello Pipecat!")) await asyncio.sleep(sleep_time_secs) - await task.queue_frame(TextFrame("Hello Pipecat!")) + await worker.queue_frame(TextFrame("Hello Pipecat!")) await asyncio.sleep(sleep_time_secs) - await task.queue_frame(TextFrame("Hello Pipecat!")) + await worker.queue_frame(TextFrame("Hello Pipecat!")) start_time = time.time() tasks = [ - asyncio.create_task(task.run(PipelineTaskParams(loop=asyncio.get_event_loop()))), + asyncio.create_task(worker.run(PipelineWorkerParams(loop=asyncio.get_event_loop()))), asyncio.create_task(delayed_frames()), ] @@ -558,7 +558,7 @@ class TestPipelineTask(unittest.IsolatedAsyncioTestCase): # reach the end of the pipeline). filter = FrameFilter(types=()) pipeline = Pipeline([filter]) - task = PipelineTask( + worker = PipelineWorker( pipeline, idle_timeout_secs=idle_timeout_secs, idle_timeout_frames=(TextFrame,), @@ -570,18 +570,18 @@ class TestPipelineTask(unittest.IsolatedAsyncioTestCase): """Sending multiple text frames. The total amount of elapsed time in this function should be greater - than the task idle timeout. If an idle timeout event is triggered it + than the worker idle timeout. If an idle timeout event is triggered it means we haven't detected that the TextFrames have been pushed. """ await asyncio.sleep(sleep_time_secs) - await task.queue_frame(TextFrame("Hello Pipecat!")) + await worker.queue_frame(TextFrame("Hello Pipecat!")) await asyncio.sleep(sleep_time_secs) - await task.queue_frame(TextFrame("Hello Pipecat!")) + await worker.queue_frame(TextFrame("Hello Pipecat!")) await asyncio.sleep(sleep_time_secs) - await task.queue_frame(TextFrame("Hello Pipecat!")) + await worker.queue_frame(TextFrame("Hello Pipecat!")) tasks = [ - asyncio.create_task(task.run(PipelineTaskParams(loop=asyncio.get_event_loop()))), + asyncio.create_task(worker.run(PipelineWorkerParams(loop=asyncio.get_event_loop()))), asyncio.create_task(delayed_frames()), ] @@ -606,21 +606,21 @@ class TestPipelineTask(unittest.IsolatedAsyncioTestCase): await self.push_frame(frame, direction) pipeline = Pipeline([CancelFilter()]) - task = PipelineTask(pipeline, cancel_timeout_secs=0.2) + worker = PipelineWorker(pipeline, cancel_timeout_secs=0.2) cancelled = False - @task.event_handler("on_pipeline_started") - async def on_pipeline_started(task: PipelineTask, frame: StartFrame): - await task.cancel() + @worker.event_handler("on_pipeline_started") + async def on_pipeline_started(worker: PipelineWorker, frame: StartFrame): + await worker.cancel() - @task.event_handler("on_pipeline_finished") - async def on_pipeline_finished(task: PipelineTask, frame: Frame): + @worker.event_handler("on_pipeline_finished") + async def on_pipeline_finished(worker: PipelineWorker, frame: Frame): nonlocal cancelled cancelled = isinstance(frame, CancelFrame) try: - await task.run(PipelineTaskParams(loop=asyncio.get_event_loop())) + await worker.run(PipelineWorkerParams(loop=asyncio.get_event_loop())) except asyncio.CancelledError: assert cancelled @@ -640,18 +640,18 @@ class TestPipelineTask(unittest.IsolatedAsyncioTestCase): error_received = False pipeline = Pipeline([ErrorProcessor()]) - task = PipelineTask(pipeline) + worker = PipelineWorker(pipeline) - @task.event_handler("on_pipeline_error") - async def on_pipeline_error(task: PipelineTask, frame: ErrorFrame): + @worker.event_handler("on_pipeline_error") + async def on_pipeline_error(worker: PipelineWorker, frame: ErrorFrame): nonlocal error_received error_received = True - await task.cancel() + await worker.cancel() - await task.queue_frame(TextFrame(text="Hello from Pipecat!")) + await worker.queue_frame(TextFrame(text="Hello from Pipecat!")) try: - await task.run(PipelineTaskParams(loop=asyncio.get_event_loop())) + await worker.run(PipelineWorkerParams(loop=asyncio.get_event_loop())) except asyncio.CancelledError: assert error_received diff --git a/tests/test_redis_bus.py b/tests/test_redis_bus.py index 21bace720..07baf4396 100644 --- a/tests/test_redis_bus.py +++ b/tests/test_redis_bus.py @@ -9,7 +9,7 @@ import itertools import unittest from pipecat.bus import ( - BusAddTaskMessage, + BusAddWorkerMessage, BusDataMessage, BusEndMessage, BusFrameMessage, @@ -18,7 +18,7 @@ from pipecat.bus import ( ) from pipecat.bus.serializers import JSONMessageSerializer from pipecat.frames.frames import TextFrame -from pipecat.pipeline.base_task import BaseTask +from pipecat.pipeline.base_worker import BaseWorker from pipecat.processors.frame_processor import FrameDirection from pipecat.utils.asyncio.task_manager import TaskManager, TaskManagerParams @@ -133,8 +133,8 @@ class TestRedisBus(unittest.IsolatedAsyncioTestCase): await self.bus.subscribe(_make_sub(received)) await self.bus.start() - task = BaseTask("test") - msg = BusAddTaskMessage(source="parent", task=task) + worker = BaseWorker("test") + msg = BusAddWorkerMessage(source="parent", worker=worker) await self.bus.send(msg) await asyncio.sleep(0.05) @@ -144,8 +144,8 @@ class TestRedisBus(unittest.IsolatedAsyncioTestCase): self.assertEqual(len(self.redis._published), 0) # But delivered locally self.assertEqual(len(received), 1) - self.assertIsInstance(received[0], BusAddTaskMessage) - self.assertIs(received[0].task, task) + self.assertIsInstance(received[0], BusAddWorkerMessage) + self.assertIs(received[0].worker, worker) async def test_round_trip_via_subscriber(self): """Messages published are received by subscribers.""" @@ -156,7 +156,7 @@ class TestRedisBus(unittest.IsolatedAsyncioTestCase): msg = BusEndMessage(source="task_a", reason="done") await self.bus.send(msg) - # Give the reader task time to process + # Give the reader worker time to process await asyncio.sleep(0.1) await self.bus.stop() @@ -239,7 +239,7 @@ class TestRedisBus(unittest.IsolatedAsyncioTestCase): self.assertEqual(self.redis._published[0][0], "custom:channel") async def test_stop_cleans_up(self): - """stop() cancels the reader task and unsubscribes from Redis.""" + """stop() cancels the reader worker and unsubscribes from Redis.""" await self.bus.start() self.assertIsNotNone(self.bus._pubsub) self.assertIsNotNone(self.bus._reader_task) diff --git a/tests/test_registry.py b/tests/test_registry.py index 1982ab8e5..a3e46d855 100644 --- a/tests/test_registry.py +++ b/tests/test_registry.py @@ -6,45 +6,45 @@ import unittest -from pipecat.registry import TaskRegistry -from pipecat.registry.types import TaskReadyData +from pipecat.registry import WorkerRegistry +from pipecat.registry.types import WorkerReadyData class TestTaskRegistry(unittest.IsolatedAsyncioTestCase): def setUp(self): - self.registry = TaskRegistry(runner_name="runner_a") + self.registry = WorkerRegistry(runner_name="runner_a") async def test_register_local_task(self): - """Local task is registered and appears in local_tasks.""" - data = TaskReadyData(task_name="greeter", runner="runner_a") + """Local task is registered and appears in local_workers.""" + data = WorkerReadyData(worker_name="greeter", runner="runner_a") result = await self.registry.register(data) self.assertTrue(result) - self.assertIn("greeter", self.registry.local_tasks) - self.assertNotIn("greeter", self.registry.remote_tasks) + self.assertIn("greeter", self.registry.local_workers) + self.assertNotIn("greeter", self.registry.remote_workers) async def test_register_remote_task(self): - """Remote task is registered and appears in remote_tasks.""" - data = TaskReadyData(task_name="support", runner="runner_b") + """Remote task is registered and appears in remote_workers.""" + data = WorkerReadyData(worker_name="support", runner="runner_b") result = await self.registry.register(data) self.assertTrue(result) - self.assertIn("support", self.registry.remote_tasks) - self.assertNotIn("support", self.registry.local_tasks) + self.assertIn("support", self.registry.remote_workers) + self.assertNotIn("support", self.registry.local_workers) async def test_duplicate_registration_returns_false(self): """Registering the same task twice returns False.""" - data = TaskReadyData(task_name="greeter", runner="runner_a") + data = WorkerReadyData(worker_name="greeter", runner="runner_a") first = await self.registry.register(data) second = await self.registry.register(data) self.assertTrue(first) self.assertFalse(second) - self.assertEqual(self.registry.local_tasks.count("greeter"), 1) + self.assertEqual(self.registry.local_workers.count("greeter"), 1) async def test_get_local_task(self): """get() returns data for a local task.""" - data = TaskReadyData(task_name="greeter", runner="runner_a") + data = WorkerReadyData(worker_name="greeter", runner="runner_a") await self.registry.register(data) result = self.registry.get("greeter") @@ -52,7 +52,7 @@ class TestTaskRegistry(unittest.IsolatedAsyncioTestCase): async def test_get_remote_task(self): """get() returns data for a remote task.""" - data = TaskReadyData(task_name="support", runner="runner_b") + data = WorkerReadyData(worker_name="support", runner="runner_b") await self.registry.register(data) result = self.registry.get("support") @@ -64,7 +64,7 @@ class TestTaskRegistry(unittest.IsolatedAsyncioTestCase): async def test_contains(self): """__contains__ works for registered and unregistered tasks.""" - data = TaskReadyData(task_name="greeter", runner="runner_a") + data = WorkerReadyData(worker_name="greeter", runner="runner_a") await self.registry.register(data) self.assertIn("greeter", self.registry) @@ -79,7 +79,7 @@ class TestTaskRegistry(unittest.IsolatedAsyncioTestCase): await self.registry.watch("greeter", handler) - data = TaskReadyData(task_name="greeter", runner="runner_a") + data = WorkerReadyData(worker_name="greeter", runner="runner_a") await self.registry.register(data) self.assertEqual(len(received), 1) @@ -94,7 +94,7 @@ class TestTaskRegistry(unittest.IsolatedAsyncioTestCase): await self.registry.watch("greeter", handler) - data = TaskReadyData(task_name="support", runner="runner_a") + data = WorkerReadyData(worker_name="support", runner="runner_a") await self.registry.register(data) self.assertEqual(len(received), 0) @@ -108,7 +108,7 @@ class TestTaskRegistry(unittest.IsolatedAsyncioTestCase): await self.registry.watch("greeter", handler) - data = TaskReadyData(task_name="greeter", runner="runner_a") + data = WorkerReadyData(worker_name="greeter", runner="runner_a") await self.registry.register(data) await self.registry.register(data) @@ -128,7 +128,7 @@ class TestTaskRegistry(unittest.IsolatedAsyncioTestCase): await self.registry.watch("greeter", handler_a) await self.registry.watch("greeter", handler_b) - data = TaskReadyData(task_name="greeter", runner="runner_a") + data = WorkerReadyData(worker_name="greeter", runner="runner_a") await self.registry.register(data) self.assertEqual(len(received_a), 1) @@ -136,7 +136,7 @@ class TestTaskRegistry(unittest.IsolatedAsyncioTestCase): async def test_watch_fires_immediately_if_already_registered(self): """Watch handler fires immediately when the task is already registered.""" - data = TaskReadyData(task_name="greeter", runner="runner_a") + data = WorkerReadyData(worker_name="greeter", runner="runner_a") await self.registry.register(data) received = [] @@ -155,12 +155,12 @@ class TestTaskRegistry(unittest.IsolatedAsyncioTestCase): async def test_multiple_remote_runners(self): """Tasks from multiple remote runners are tracked separately.""" - data_b = TaskReadyData(task_name="task_b", runner="runner_b") - data_c = TaskReadyData(task_name="task_c", runner="runner_c") + data_b = WorkerReadyData(worker_name="task_b", runner="runner_b") + data_c = WorkerReadyData(worker_name="task_c", runner="runner_c") await self.registry.register(data_b) await self.registry.register(data_c) - remote = self.registry.remote_tasks + remote = self.registry.remote_workers self.assertIn("task_b", remote) self.assertIn("task_c", remote) self.assertEqual(len(remote), 2) diff --git a/tests/test_runner.py b/tests/test_runner.py index 67a6560c4..a48fcc6f3 100644 --- a/tests/test_runner.py +++ b/tests/test_runner.py @@ -8,44 +8,44 @@ import asyncio import unittest from pipecat.bus import ( - BusAddTaskMessage, + BusAddWorkerMessage, BusCancelMessage, - BusCancelTaskMessage, + BusCancelWorkerMessage, BusEndMessage, - BusEndTaskMessage, + BusEndWorkerMessage, ) -from pipecat.pipeline.base_task import BaseTask +from pipecat.pipeline.base_worker import BaseWorker from pipecat.pipeline.runner import PipelineRunner -class StubTask(BaseTask): - """BaseTask subclass that stops on end/cancel so the runner can exit.""" +class StubTask(BaseWorker): + """BaseWorker subclass that stops on end/cancel so the runner can exit.""" - async def _handle_task_end(self, message): - await super()._handle_task_end(message) + async def _handle_worker_end(self, message): + await super()._handle_worker_end(message) self._finished_event.set() - async def _handle_task_cancel(self, message): - await super()._handle_task_cancel(message) + async def _handle_worker_cancel(self, message): + await super()._handle_worker_cancel(message) self._finished_event.set() class TestPipelineRunner(unittest.IsolatedAsyncioTestCase): async def test_spawn_registers_task(self): - """spawn() registers the task by name (duplicate is silently skipped).""" + """add_worker() registers the task by name (duplicate is silently skipped).""" runner = PipelineRunner(handle_sigint=False) task = StubTask("task_a") - await runner.spawn(task) + await runner.add_worker(task) # Duplicate is silently skipped (logs error) - await runner.spawn(StubTask("task_a")) + await runner.add_worker(StubTask("task_a")) async def test_run_starts_bus_and_tasks(self): """run() starts bus, starts all tasks, fires on_ready.""" runner = PipelineRunner(handle_sigint=False) task = StubTask("task_a") - await runner.spawn(task) + await runner.add_worker(task) runner_started = asyncio.Event() @@ -63,7 +63,7 @@ class TestPipelineRunner(unittest.IsolatedAsyncioTestCase): """end() is idempotent — subsequent calls are no-ops.""" runner = PipelineRunner(handle_sigint=False) task = StubTask("task_a") - await runner.spawn(task) + await runner.add_worker(task) @runner.event_handler("on_ready") async def on_ready(runner): @@ -77,7 +77,7 @@ class TestPipelineRunner(unittest.IsolatedAsyncioTestCase): """cancel() is idempotent — subsequent calls are no-ops.""" runner = PipelineRunner(handle_sigint=False) task = StubTask("task_a") - await runner.spawn(task) + await runner.add_worker(task) @runner.event_handler("on_ready") async def on_ready(runner): @@ -90,14 +90,14 @@ class TestPipelineRunner(unittest.IsolatedAsyncioTestCase): pass async def test_end_sends_end_task_message_to_root_tasks_only(self): - """end() sends BusEndTaskMessage only to root tasks (no parent).""" + """end() sends BusEndWorkerMessage only to root tasks (no parent).""" runner = PipelineRunner(handle_sigint=False) root = StubTask("root") child = StubTask("child") # Manually mark child as having root as parent child._parent = root.name - await runner.spawn(root) - await runner.spawn(child) + await runner.add_worker(root) + await runner.add_worker(child) sent = [] bus = runner.bus @@ -112,19 +112,19 @@ class TestPipelineRunner(unittest.IsolatedAsyncioTestCase): # Call end() directly — no need to run the full pipeline lifecycle await runner.end() - end_msgs = [m for m in sent if isinstance(m, BusEndTaskMessage)] + end_msgs = [m for m in sent if isinstance(m, BusEndWorkerMessage)] targets = {m.target for m in end_msgs} self.assertIn("root", targets) self.assertNotIn("child", targets) async def test_cancel_sends_cancel_task_message_to_root_tasks_only(self): - """cancel() sends BusCancelTaskMessage only to root tasks (no parent).""" + """cancel() sends BusCancelWorkerMessage only to root tasks (no parent).""" runner = PipelineRunner(handle_sigint=False) root = StubTask("root") child = StubTask("child") child._parent = root.name - await runner.spawn(root) - await runner.spawn(child) + await runner.add_worker(root) + await runner.add_worker(child) sent = [] bus = runner.bus @@ -139,7 +139,7 @@ class TestPipelineRunner(unittest.IsolatedAsyncioTestCase): # Call cancel() directly — no need to run the full pipeline lifecycle await runner.cancel() - cancel_msgs = [m for m in sent if isinstance(m, BusCancelTaskMessage)] + cancel_msgs = [m for m in sent if isinstance(m, BusCancelWorkerMessage)] targets = {m.target for m in cancel_msgs} self.assertIn("root", targets) self.assertNotIn("child", targets) @@ -148,7 +148,7 @@ class TestPipelineRunner(unittest.IsolatedAsyncioTestCase): """BusEndMessage on bus triggers runner.end().""" runner = PipelineRunner(handle_sigint=False) task = StubTask("task_a") - await runner.spawn(task) + await runner.add_worker(task) bus = runner.bus @@ -164,7 +164,7 @@ class TestPipelineRunner(unittest.IsolatedAsyncioTestCase): """BusCancelMessage on bus triggers runner.cancel().""" runner = PipelineRunner(handle_sigint=False) task = StubTask("task_a") - await runner.spawn(task) + await runner.add_worker(task) bus = runner.bus @@ -177,25 +177,25 @@ class TestPipelineRunner(unittest.IsolatedAsyncioTestCase): except asyncio.CancelledError: pass - async def test_bus_add_task_message_triggers_spawn(self): - """BusAddTaskMessage on bus triggers spawn().""" + async def test_bus_add_task_message_triggers_add(self): + """BusAddWorkerMessage on bus triggers add_worker().""" runner = PipelineRunner(handle_sigint=False) task_a = StubTask("task_a") - await runner.spawn(task_a) + await runner.add_worker(task_a) task_b = StubTask("task_b") bus = runner.bus @runner.event_handler("on_ready") async def on_ready(runner): - await bus.send(BusAddTaskMessage(source="task_a", task=task_b)) + await bus.send(BusAddWorkerMessage(source="task_a", task=task_b)) await asyncio.sleep(0.1) await runner.end() await asyncio.wait_for(runner.run(), timeout=5.0) # Verify task_b was added (duplicate is silently skipped) - await runner.spawn(StubTask("task_b")) + await runner.add_worker(StubTask("task_b")) if __name__ == "__main__": diff --git a/tests/test_serializers.py b/tests/test_serializers.py index d3ef97ad0..775f83d32 100644 --- a/tests/test_serializers.py +++ b/tests/test_serializers.py @@ -9,7 +9,7 @@ import unittest from pydantic import BaseModel from pipecat.bus.messages import ( - BusActivateTaskMessage, + BusActivateWorkerMessage, BusCancelMessage, BusDataMessage, BusEndMessage, @@ -60,8 +60,8 @@ class TestJSONMessageSerializer(unittest.TestCase): self.assertIsNone(restored.target) def test_round_trip_activate_message(self): - """BusActivateTaskMessage with args round-trips.""" - msg = BusActivateTaskMessage( + """BusActivateWorkerMessage with args round-trips.""" + msg = BusActivateWorkerMessage( source="parent", target="child", args={"messages": [{"role": "user", "content": "hello"}]}, @@ -69,7 +69,7 @@ class TestJSONMessageSerializer(unittest.TestCase): data = self.serializer.serialize(msg) restored = self.serializer.deserialize(data) - self.assertIsInstance(restored, BusActivateTaskMessage) + self.assertIsInstance(restored, BusActivateWorkerMessage) self.assertEqual(restored.source, "parent") self.assertEqual(restored.target, "child") self.assertEqual(restored.args["messages"][0]["content"], "hello") diff --git a/tests/test_startup_timing_observer.py b/tests/test_startup_timing_observer.py index 6355c6081..af2d2ca58 100644 --- a/tests/test_startup_timing_observer.py +++ b/tests/test_startup_timing_observer.py @@ -181,7 +181,7 @@ class TestStartupTimingObserver(unittest.IsolatedAsyncioTestCase): report = reports[0] # No internal processors (PipelineSource, PipelineSink, Pipeline) in the report. - internal_names = ("Pipeline#", "PipelineTask#") + internal_names = ("Pipeline#", "PipelineWorker#") for t in report.processor_timings: for prefix in internal_names: self.assertNotIn( diff --git a/tests/test_turn_trace_observer.py b/tests/test_turn_trace_observer.py index 41ff41b8b..56f4176d6 100644 --- a/tests/test_turn_trace_observer.py +++ b/tests/test_turn_trace_observer.py @@ -133,7 +133,7 @@ class TestTurnTraceObserver(unittest.IsolatedAsyncioTestCase): observers=self._all_observers(trace_observer), ) - # End conversation to flush the conversation span (normally done by PipelineTask._cleanup) + # End conversation to flush the conversation span (normally done by PipelineWorker._cleanup) trace_observer.end_conversation_tracing() conv_spans = self._get_spans_by_name("conversation") @@ -320,7 +320,7 @@ class TestTurnTraceObserver(unittest.IsolatedAsyncioTestCase): observers=self._all_observers(trace_observer), ) - # Manually end conversation tracing (as PipelineTask._cleanup does) + # Manually end conversation tracing (as PipelineWorker._cleanup does) trace_observer.end_conversation_tracing() self.assertIsNone(tracing_ctx.get_conversation_context()) diff --git a/tests/test_vonage_video_connector.py b/tests/test_vonage_video_connector.py index f8d874fa9..2d33a150d 100644 --- a/tests/test_vonage_video_connector.py +++ b/tests/test_vonage_video_connector.py @@ -12,6 +12,7 @@ from collections.abc import Awaitable, Callable from concurrent.futures import ThreadPoolExecutor from dataclasses import dataclass from datetime import datetime, timedelta +from types import SimpleNamespace from typing import Any, Optional from unittest.mock import ANY, AsyncMock, MagicMock, Mock, call, patch @@ -247,7 +248,11 @@ class TestVonageVideoConnectorTransport: clock: SystemClock = SystemClock() # type: ignore[no-untyped-call] task_manager = TaskManager() task_manager.setup(TaskManagerParams(loop=asyncio.get_running_loop())) - self._frame_processor_setup = FrameProcessorSetup(clock=clock, task_manager=task_manager) + self._frame_processor_setup = FrameProcessorSetup( + clock=clock, + task_manager=task_manager, + pipeline_worker=SimpleNamespace(app_resources=None), # type: ignore[arg-type] + ) return self._frame_processor_setup async def _wait_for_condition( diff --git a/tests/test_websocket_proxy.py b/tests/test_websocket_proxy.py index b0f630e10..89f8fc28e 100644 --- a/tests/test_websocket_proxy.py +++ b/tests/test_websocket_proxy.py @@ -10,12 +10,12 @@ from unittest.mock import MagicMock from pipecat.bus import ( AsyncQueueBus, - BusAddTaskMessage, + BusAddWorkerMessage, BusDataMessage, ) from pipecat.bus.serializers import JSONMessageSerializer -from pipecat.pipeline.base_task import BaseTask -from pipecat.registry import TaskRegistry +from pipecat.pipeline.base_worker import BaseWorker +from pipecat.registry import WorkerRegistry from pipecat.utils.asyncio.task_manager import TaskManager, TaskManagerParams @@ -85,17 +85,17 @@ class FakeStarletteWebSocket: class TestWebSocketProxyClientTask(unittest.IsolatedAsyncioTestCase): async def asyncSetUp(self): self.bus, self.tm = await create_test_bus() - self.registry = TaskRegistry(runner_name="test-runner") + self.registry = WorkerRegistry(runner_name="test-runner") self.serializer = JSONMessageSerializer() async def _create_client(self, fake_ws): - from pipecat.tasks.proxy.websocket.client import WebSocketProxyClientTask + from pipecat.workers.proxy.websocket.client import WebSocketProxyClientTask task = WebSocketProxyClientTask( "proxy", url="ws://fake", - remote_task_name="worker", - local_task_name="voice", + remote_worker_name="worker", + local_worker_name="voice", serializer=self.serializer, ) task.attach(registry=self.registry, bus=self.bus) @@ -141,9 +141,9 @@ class TestWebSocketProxyClientTask(unittest.IsolatedAsyncioTestCase): fake_ws = FakeWebSocket() task = await self._create_client(fake_ws) - stub = MagicMock(spec=BaseTask) + stub = MagicMock(spec=BaseWorker) stub.name = "child" - msg = BusAddTaskMessage(source="parent", target="worker", task=stub) + msg = BusAddWorkerMessage(source="parent", target="worker", worker=stub) await task.on_bus_message(msg) self.assertEqual(len(fake_ws._sent), 0) @@ -208,17 +208,17 @@ class TestWebSocketProxyClientTask(unittest.IsolatedAsyncioTestCase): class TestWebSocketProxyServerTask(unittest.IsolatedAsyncioTestCase): async def asyncSetUp(self): self.bus, self.tm = await create_test_bus() - self.registry = TaskRegistry(runner_name="test-runner") + self.registry = WorkerRegistry(runner_name="test-runner") self.serializer = JSONMessageSerializer() async def _create_server(self, fake_ws): - from pipecat.tasks.proxy.websocket.server import WebSocketProxyServerTask + from pipecat.workers.proxy.websocket.server import WebSocketProxyServerTask task = WebSocketProxyServerTask( "gateway", websocket=fake_ws, - task_name="worker", - remote_task_name="voice", + worker_name="worker", + remote_worker_name="voice", serializer=self.serializer, ) task.attach(registry=self.registry, bus=self.bus)