|
4 | 4 | import copy |
5 | 5 | import json |
6 | 6 | import uuid |
| 7 | +import warnings |
7 | 8 |
|
8 | 9 | from abc import ABC, abstractmethod |
9 | 10 | from contextlib import contextmanager |
|
152 | 153 | "LMStudioPredictionError", |
153 | 154 | "LMStudioPresetNotFoundError", |
154 | 155 | "LMStudioServerError", |
155 | | - "LMStudioUnknownMessageError", |
| 156 | + "LMStudioUnknownMessageWarning", |
156 | 157 | "LMStudioWebsocketError", |
157 | 158 | "ModelInfo", |
158 | 159 | "ModelInstanceInfo", |
@@ -414,7 +415,7 @@ class LMStudioClientError(LMStudioError): |
414 | 415 |
|
415 | 416 |
|
416 | 417 | @sdk_public_type |
417 | | -class LMStudioUnknownMessageError(LMStudioClientError): |
| 418 | +class LMStudioUnknownMessageWarning(LMStudioClientError, UserWarning): |
418 | 419 | """Client has received a message in a format it wasn't expecting.""" |
419 | 420 |
|
420 | 421 |
|
@@ -699,11 +700,19 @@ def result(self) -> T: |
699 | 700 | assert self._result is not None |
700 | 701 | return self._result |
701 | 702 |
|
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 |
707 | 716 | ) |
708 | 717 |
|
709 | 718 | # See ChannelHandler below for more details on the routing of received messages |
@@ -797,7 +806,7 @@ def iter_message_events( |
797 | 806 | case {"type": "success", "defaultIdentifier": str(default_identifier)}: |
798 | 807 | yield self._set_result(default_identifier) |
799 | 808 | case unmatched: |
800 | | - self.raise_unknown_message_error(unmatched) |
| 809 | + self.report_unknown_message(unmatched) |
801 | 810 |
|
802 | 811 | def handle_rx_event(self, event: ModelDownloadRxEvent) -> None: |
803 | 812 | match event: |
@@ -921,7 +930,7 @@ def iter_message_events( |
921 | 930 | ) |
922 | 931 | yield self._set_result(result) |
923 | 932 | case unmatched: |
924 | | - self.raise_unknown_message_error(unmatched) |
| 933 | + self.report_unknown_message(unmatched) |
925 | 934 |
|
926 | 935 | def handle_rx_event(self, event: ModelLoadingRxEvent) -> None: |
927 | 936 | match event: |
@@ -1290,7 +1299,7 @@ def iter_message_events( |
1290 | 1299 | ) |
1291 | 1300 | ) |
1292 | 1301 | case unmatched: |
1293 | | - self.raise_unknown_message_error(unmatched) |
| 1302 | + self.report_unknown_message(unmatched) |
1294 | 1303 |
|
1295 | 1304 | def handle_rx_event(self, event: PredictionRxEvent) -> None: |
1296 | 1305 | match event: |
|
0 commit comments