# runners/echo.py from __future__ import annotations from typing import Any, Dict, Optional from .base import ILLMRunner from models import LLMServiceObj from function_tracker import FunctionCallTracker import logging logger = logging.getLogger(__name__) class EchoRunner(ILLMRunner): Type = "TurboLLM" IsEnabled = True IsStateStarting = False IsStateFailed = False def __init__(self, publisher, settings): self._pub = publisher self._settings = settings self._tracker = FunctionCallTracker() async def StartProcess(self, llmServiceObj: dict) -> None: logger.info(f"StartProcess called with: {llmServiceObj}") # pretend to “warm up” pass async def RemoveProcess(self, sessionId: str) -> None: logger.info(f"RemoveProcess called for session: {sessionId}") # nothing to clean here pass async def StopRequest(self, sessionId: str) -> None: logger.info(f"StopRequest called for session: {sessionId}") # no streaming loop to stop in echo pass async def SendInputAndGetResponse(self, llmServiceObj: dict) -> None: logger.info(f"SendInputAndGetResponse called with: {llmServiceObj}") llm = LLMServiceObj(**llmServiceObj) if llm.UserInput.startswith("<|START_AUDIO|>") or llm.UserInput.startswith("<|STOP_AUDIO|>"): logger.debug("Audio input detected, ignoring in echo.") return # Echo behavior (match UI format) await self._pub.publish("llmServiceMessage", LLMServiceObj(LlmMessage=f" {llm.UserInput}\n\n")) await self._pub.publish("llmServiceMessage", LLMServiceObj(LlmMessage=f" You said: {llm.UserInput}\n")) await self._pub.publish("llmServiceMessage", LLMServiceObj(LlmMessage=""))