import os
from pipecat.audio.vad.silero import SileroVADAnalyzer
from pipecat.frames.frames import LLMUpdateSettingsFrame
from pipecat.pipeline.pipeline import Pipeline
from pipecat.pipeline.worker import PipelineWorker
from pipecat.processors.aggregators.llm_context import LLMContext
from pipecat.processors.aggregators.llm_response_universal import (
LLMContextAggregatorPair,
LLMUserAggregatorParams,
)
from pipecat.runner.types import RunnerArguments
from pipecat.runner.utils import create_transport
from pipecat.services.openai.llm import OpenAILLMService
from pipecat.services.settings import LLMSettings
from pipecat.transcriptions.language import Language
from pipecat.transports.base_transport import TransportParams
from pipecat.workers.runner import WorkerRunner
from pipecat_slng import SlngSTTService, SlngTTSService
from salon import agent as salon
from unmute_core.agent import AgentSpec
from unmute_core.pipecat import UnmuteFlows, greeting_frames
SLNG_KEY = os.environ["SLNG_API_KEY"]
WORLD_PART = os.environ["SLNG_WORLD_PART"]
VOICE = "8d8aec63a56c460cb7def795bdf754fa"
transport_params = {
"webrtc": lambda: TransportParams(audio_in_enabled=True, audio_out_enabled=True),
}
async def bot(runner_args: RunnerArguments) -> None:
"""Run one call: start Robin, then say the greeting."""
transport = await create_transport(runner_args, transport_params)
llm = OpenAILLMService(settings=OpenAILLMService.Settings(model="gpt-5.6-terra"))
context = LLMContext()
aggregators = LLMContextAggregatorPair(
context, user_params=LLMUserAggregatorParams(vad_analyzer=SileroVADAnalyzer())
)
spec = AgentSpec(salon.CONCIERGE_PROMPT)
flows = UnmuteFlows(spec, llm=llm, context=context, aggregators=aggregators)
flows.install()
pipeline = Pipeline(
[
transport.input(),
SlngSTTService(
api_key=SLNG_KEY,
world_part=WORLD_PART,
model="soniox/speech-ai:rt-v5",
language=Language.EN,
),
aggregators.user(),
llm,
SlngTTSService(
api_key=SLNG_KEY,
world_part=WORLD_PART,
model="slng/fish/tts:s2.1-pro",
voice=VOICE,
language=Language.EN,
),
transport.output(),
aggregators.assistant(),
]
)
worker = PipelineWorker(pipeline)
@transport.event_handler("on_client_connected")
async def greet(transport, client) -> None:
"""Set the prompt, then say the greeting."""
await worker.queue_frames(
[
LLMUpdateSettingsFrame(
delta=LLMSettings(system_instruction=flows.main_instruction())
),
*greeting_frames(salon.GREETING, None),
]
)
runner = WorkerRunner(handle_sigint=runner_args.handle_sigint)
await runner.add_workers(worker)
await runner.run()
if __name__ == "__main__":
from pipecat.runner.run import main
main()