Rename BaseTask → BaseWorker and reserve "task" for asyncio

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.
This commit is contained in:
Aleix Conchillo Flaqué
2026-05-20 16:39:45 -07:00
parent b9aed0d673
commit b03247f360
394 changed files with 4602 additions and 4487 deletions

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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()}")

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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__":

View File

@@ -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):

View File

@@ -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):

View File

@@ -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__":

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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__":

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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 <token>"},
)
```

View File

@@ -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()

View File

@@ -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

View File

@@ -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",

View File

@@ -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"),

View File

@@ -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")

View File

@@ -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")

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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",

View File

@@ -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()

View File

@@ -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__":

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

Some files were not shown because too many files have changed in this diff Show More