|
38 | 38 | Omit = None |
39 | 39 |
|
40 | 40 | from anthropic.resources import AsyncMessages, Messages |
41 | | - from anthropic.lib.streaming._messages import MessageStreamManager |
| 41 | + from anthropic.lib.streaming._messages import ( |
| 42 | + MessageStreamManager, |
| 43 | + AsyncMessageStreamManager, |
| 44 | + ) |
42 | 45 |
|
43 | 46 | from anthropic.types import ( |
44 | 47 | MessageStartEvent, |
|
66 | 69 | ModelParam, |
67 | 70 | TextBlockParam, |
68 | 71 | ToolUnionParam, |
| 72 | + AsyncMessageStream, |
69 | 73 | ) |
70 | 74 |
|
71 | 75 |
|
@@ -96,6 +100,13 @@ def setup_once() -> None: |
96 | 100 | MessageStreamManager.__enter__ |
97 | 101 | ) |
98 | 102 |
|
| 103 | + AsyncMessages.stream = _wrap_async_message_stream(AsyncMessages.stream) |
| 104 | + AsyncMessageStreamManager.__aenter__ = ( |
| 105 | + _wrap_async_message_stream_manager_aenter( |
| 106 | + AsyncMessageStreamManager.__aenter__ |
| 107 | + ) |
| 108 | + ) |
| 109 | + |
99 | 110 |
|
100 | 111 | def _capture_exception(exc: "Any") -> None: |
101 | 112 | set_span_errored() |
@@ -824,6 +835,61 @@ def _sentry_patched_enter(self: "MessageStreamManager") -> "MessageStreamManager |
824 | 835 | return _sentry_patched_enter |
825 | 836 |
|
826 | 837 |
|
| 838 | +def _wrap_async_message_stream(f: "Any") -> "Any": |
| 839 | + """ |
| 840 | + Attaches user-provided arguments to the returned context manager. |
| 841 | + The attributes are set on `gen_ai.chat` spans in the patch for the context manager. |
| 842 | + """ |
| 843 | + |
| 844 | + @wraps(f) |
| 845 | + def _sentry_patched_stream( |
| 846 | + *args: "Any", **kwargs: "Any" |
| 847 | + ) -> "AsyncMessageStreamManager": |
| 848 | + stream_manager = f(*args, **kwargs) |
| 849 | + |
| 850 | + stream_manager._max_tokens = kwargs.get("max_tokens") |
| 851 | + stream_manager._messages = kwargs.get("messages") |
| 852 | + stream_manager._model = kwargs.get("model") |
| 853 | + stream_manager._system = kwargs.get("system") |
| 854 | + stream_manager._temperature = kwargs.get("temperature") |
| 855 | + stream_manager._top_k = kwargs.get("top_k") |
| 856 | + stream_manager._top_p = kwargs.get("top_p") |
| 857 | + stream_manager._tools = kwargs.get("tools") |
| 858 | + |
| 859 | + return stream_manager |
| 860 | + |
| 861 | + return _sentry_patched_stream |
| 862 | + |
| 863 | + |
| 864 | +def _wrap_async_message_stream_manager_aenter(f: "Any") -> "Any": |
| 865 | + """ |
| 866 | + Creates and manages `gen_ai.chat` spans. |
| 867 | + """ |
| 868 | + |
| 869 | + @wraps(f) |
| 870 | + async def _sentry_patched_aenter( |
| 871 | + self: "MessageStreamManager", |
| 872 | + ) -> "AsyncMessageStream": |
| 873 | + stream = await f(self) |
| 874 | + if not hasattr(self, "_max_tokens"): |
| 875 | + return stream |
| 876 | + |
| 877 | + _sentry_patched_stream_common( |
| 878 | + stream=stream, |
| 879 | + max_tokens=self._max_tokens, |
| 880 | + messages=self._messages, |
| 881 | + model=self._model, |
| 882 | + system=self._system, |
| 883 | + temperature=self._temperature, |
| 884 | + top_k=self._top_k, |
| 885 | + top_p=self._top_p, |
| 886 | + tools=self._tools, |
| 887 | + ) |
| 888 | + return stream |
| 889 | + |
| 890 | + return _sentry_patched_aenter |
| 891 | + |
| 892 | + |
827 | 893 | def _is_given(obj: "Any") -> bool: |
828 | 894 | """ |
829 | 895 | Check for givenness safely across different anthropic versions. |
|
0 commit comments