Skip to content

Commit 2741780

Browse files
authored
Improve channel forward compatibility (#103)
Unknown messages are now filtered through Python's warning machinery rather than always raising an immediate exception.
1 parent 852b06e commit 2741780

File tree

1 file changed

+19
-10
lines changed

1 file changed

+19
-10
lines changed

src/lmstudio/json_api.py

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import copy
55
import json
66
import uuid
7+
import warnings
78

89
from abc import ABC, abstractmethod
910
from contextlib import contextmanager
@@ -152,7 +153,7 @@
152153
"LMStudioPredictionError",
153154
"LMStudioPresetNotFoundError",
154155
"LMStudioServerError",
155-
"LMStudioUnknownMessageError",
156+
"LMStudioUnknownMessageWarning",
156157
"LMStudioWebsocketError",
157158
"ModelInfo",
158159
"ModelInstanceInfo",
@@ -414,7 +415,7 @@ class LMStudioClientError(LMStudioError):
414415

415416

416417
@sdk_public_type
417-
class LMStudioUnknownMessageError(LMStudioClientError):
418+
class LMStudioUnknownMessageWarning(LMStudioClientError, UserWarning):
418419
"""Client has received a message in a format it wasn't expecting."""
419420

420421

@@ -699,11 +700,19 @@ def result(self) -> T:
699700
assert self._result is not None
700701
return self._result
701702

702-
def raise_unknown_message_error(self, unknown_message: Any) -> NoReturn:
703-
# TODO: improve forward compatibility by switching this to use warnings.warn
704-
# instead of failing immediately for all unknown messages
705-
raise LMStudioUnknownMessageError(
706-
f"{self._NOTICE_PREFIX} unexpected message contents: {unknown_message!r}"
703+
def report_unknown_message(self, unknown_message: Any) -> None:
704+
# By default, each unique unknown message will be reported once per
705+
# calling code location, NOT per channel instance. This is reasonable,
706+
# since it generally indicates an SDK/server version compatibility issue,
707+
# not a problem with any specific instance
708+
# Potentially useful warnings filters:
709+
# * Always show: "always:LMStudioUnknownMessageWarning"
710+
# * Never show: "ignore:LMStudioUnknownMessageWarning"
711+
# * Client exception: "error:LMStudioUnknownMessageWarning"
712+
warnings.warn(
713+
f"{self._NOTICE_PREFIX} unexpected message contents: {unknown_message!r}",
714+
LMStudioUnknownMessageWarning,
715+
stacklevel=2, # Handle based on caller's code location
707716
)
708717

709718
# See ChannelHandler below for more details on the routing of received messages
@@ -797,7 +806,7 @@ def iter_message_events(
797806
case {"type": "success", "defaultIdentifier": str(default_identifier)}:
798807
yield self._set_result(default_identifier)
799808
case unmatched:
800-
self.raise_unknown_message_error(unmatched)
809+
self.report_unknown_message(unmatched)
801810

802811
def handle_rx_event(self, event: ModelDownloadRxEvent) -> None:
803812
match event:
@@ -921,7 +930,7 @@ def iter_message_events(
921930
)
922931
yield self._set_result(result)
923932
case unmatched:
924-
self.raise_unknown_message_error(unmatched)
933+
self.report_unknown_message(unmatched)
925934

926935
def handle_rx_event(self, event: ModelLoadingRxEvent) -> None:
927936
match event:
@@ -1290,7 +1299,7 @@ def iter_message_events(
12901299
)
12911300
)
12921301
case unmatched:
1293-
self.raise_unknown_message_error(unmatched)
1302+
self.report_unknown_message(unmatched)
12941303

12951304
def handle_rx_event(self, event: PredictionRxEvent) -> None:
12961305
match event:

0 commit comments

Comments
 (0)