Skip to content

Commit

Permalink
Merge pull request #12 from rakeshv247/debug-mode
Browse files Browse the repository at this point in the history
Introducting LLM debug mode
  • Loading branch information
rakeshv247 authored Feb 14, 2025
2 parents 197fe3f + 4914991 commit 9e4bf00
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 3 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [0.1.0] - 2025-02-13

### Added

- Added Debug mode
- Introduced a new debug field in `StartConversation`.
- When LLM debug mode is enabled, the client will receive debug messages with LLM request and response content

## [0.0.9] - 2025-01-24

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.0.9
0.1.0
6 changes: 6 additions & 0 deletions speechmatics_flow/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
Interaction,
ConnectionSettings,
PlaybackSettings,
DebugMode,
)
from speechmatics_flow.templates import TemplateOptions

Expand Down Expand Up @@ -159,6 +160,10 @@ def get_playback_settings(args):
)


def get_debug_mode_settings(args):
return DebugMode(llm=args.get("llm_debug_enabled"))


# pylint: disable=too-many-arguments,too-many-statements
def add_printing_handlers(
api,
Expand Down Expand Up @@ -284,6 +289,7 @@ def run(stream):
audio_settings=get_audio_settings(args),
conversation_config=get_conversation_config(args),
playback_settings=get_playback_settings(args),
debug_mode=get_debug_mode_settings(args),
from_cli=True,
)
except KeyboardInterrupt:
Expand Down
6 changes: 6 additions & 0 deletions speechmatics_flow/cli_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,12 @@ def get_arg_parser():
choices=[k for k in TemplateOptions.keys()],
help="Choose your assistant.",
)
parser.add_argument(
"--llm-debug-enabled",
default=False,
action="store_true",
help="Flag indicating whether to receive conversations between the LLM and the Flow backend in debug messages.",
)

return parser

Expand Down
11 changes: 11 additions & 0 deletions speechmatics_flow/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
Interaction,
PlaybackSettings,
ServerMessageType,
DebugMode,
)
from speechmatics_flow.tool_function_param import ToolFunctionParam
from speechmatics_flow.utils import read_in_chunks, json_utf8
Expand Down Expand Up @@ -67,6 +68,7 @@ def __init__(
self.audio_settings = None
self.playback_settings = None
self.tools = None
self.debug_mode = None

self.event_handlers = {x: [] for x in ServerMessageType}
self.middlewares = {x: [] for x in ClientMessageType}
Expand Down Expand Up @@ -148,6 +150,10 @@ def _start_conversation(self):
}
if self.tools is not None:
msg["tools"] = self.tools

if self.debug_mode:
msg["debug"] = self.debug_mode.asdict()

self.session_running = True
self._call_middleware(ClientMessageType.StartConversation, msg, False)
LOGGER.debug(msg)
Expand Down Expand Up @@ -564,6 +570,7 @@ async def run(
from_cli: bool = False,
tools: Optional[List[ToolFunctionParam]] = None,
playback_settings: PlaybackSettings = PlaybackSettings(),
debug_mode: DebugMode = None,
):
"""
Begin a new recognition session.
Expand All @@ -586,6 +593,9 @@ async def run(
:param playback_settings: Configuration for the playback stream.
:type playback_settings: models.PlaybackSettings
:param debug_mode: Configuration to receive debug messages from Flow
:type debug_mode: models.DebugMode
:raises Exception: Can raise any exception returned by the
consumer/producer tasks.
Expand All @@ -596,6 +606,7 @@ async def run(
self.audio_settings = audio_settings
self.playback_settings = playback_settings
self.tools = tools
self.debug_mode = debug_mode

await self._init_synchronization_primitives()

Expand Down
17 changes: 16 additions & 1 deletion speechmatics_flow/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,18 @@ def asdict(self):
)


@dataclass
class DebugMode:
"""Defines debug flags for monitoring and troubleshooting Flow"""

llm: bool = False
"""Optional Flag indicating whether to receive conversations between the LLM and the Flow backend as
debug messages."""

def asdict(self):
return asdict(self)


class ClientMessageType(str, Enum):
# pylint: disable=invalid-name
"""Defines various messages sent from client to server."""
Expand Down Expand Up @@ -179,7 +191,10 @@ class ServerMessageType(str, Enum):
"""Indicates a generic warning message."""

Error = "Error"
"""Indicates n generic error message."""
"""Indicates a generic error message."""

Debug = "Debug"
"""Indicates a debug message"""


@dataclass
Expand Down
15 changes: 15 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,18 @@ def test_get_conversation_config(args, exp_values):
assert config.asdict() == exp_values, "Expecting {} but got {}".format(
exp_values, config.asdict()
)


@mark.parametrize(
"args, exp_values",
[
param([], {"llm": False}),
param(["--llm-debug-enabled"], {"llm": True}),
],
)
def test_get_debug_mode_settings(args, exp_values):
test_args = vars(cli.parse_args(args=args))
config = cli.get_debug_mode_settings(test_args)
assert (
config.asdict() == exp_values
), f"Expecting {exp_values}, got {config.asdict()}"
21 changes: 20 additions & 1 deletion tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import pytest
from pytest import param

from speechmatics_flow import DebugMode
from speechmatics_flow.client import WebsocketClient
from speechmatics_flow.models import (
ServerMessageType,
Expand Down Expand Up @@ -33,23 +34,26 @@ def ws_client():


@pytest.mark.parametrize(
"audio_format, conversation_config, tools, expected_start_message",
"audio_format, conversation_config, tools, debug_mode, expected_start_message",
[
param(
AudioSettings(),
ConversationConfig(),
None,
DebugMode(),
{
"message": ClientMessageType.StartConversation.value,
"audio_format": AudioSettings().asdict(),
"conversation_config": ConversationConfig().asdict(),
"debug": DebugMode().asdict(),
},
id="with default values",
),
param(
AudioSettings(),
ConversationConfig(),
[TOOL_FUNCTION],
None,
{
"message": ClientMessageType.StartConversation.value,
"audio_format": AudioSettings().asdict(),
Expand All @@ -58,13 +62,27 @@ def ws_client():
},
id="with default values and tools",
),
param(
AudioSettings(),
ConversationConfig(),
None,
DebugMode(llm=True),
{
"message": ClientMessageType.StartConversation.value,
"audio_format": AudioSettings().asdict(),
"conversation_config": ConversationConfig().asdict(),
"debug": DebugMode(llm=True).asdict(),
},
id="with default values and llm debug mode enabled",
),
],
)
def test_start_conversation(
ws_client: WebsocketClient,
audio_format: AudioSettings,
conversation_config: ConversationConfig,
tools: Optional[List[ToolFunctionParam]],
debug_mode: Optional[DebugMode],
expected_start_message: Dict,
):
handler_called = False
Expand All @@ -77,6 +95,7 @@ def handler(*_):
ws_client.audio_settings = audio_format
ws_client.conversation_config = conversation_config
ws_client.tools = tools
ws_client.debug_mode = debug_mode
start_conversation_msg = ws_client._start_conversation()
assert start_conversation_msg == json.dumps(
expected_start_message
Expand Down
14 changes: 14 additions & 0 deletions tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,17 @@ def test_playback_settings(config, want):
audio_settings = models.PlaybackSettings(**config)
got = asdict(audio_settings)
assert got == want


@pytest.mark.parametrize(
"config, want",
[
({}, {"llm": False}),
({"llm": False}, {"llm": False}),
({"llm": True}, {"llm": True}),
],
)
def test_debug_mode(config, want):
debug_mode_settings = models.DebugMode(**config)
got = debug_mode_settings.asdict()
assert got == want

0 comments on commit 9e4bf00

Please sign in to comment.