Skip to content

Commit 532b4f2

Browse files
committed
Updates for recent anthropic release; be more careful not to error out when checking whether message can be normalized
1 parent e12cca0 commit 532b4f2

File tree

1 file changed

+44
-12
lines changed

1 file changed

+44
-12
lines changed

shiny/ui/_chat_types.py

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from abc import ABC, abstractmethod
2-
from typing import TYPE_CHECKING, Any, Literal, Optional, TypedDict, cast
2+
from typing import TYPE_CHECKING, Any, Literal, Optional, TypedDict, Union, cast
33

44
from typing_extensions import NotRequired
55

@@ -142,44 +142,76 @@ def can_normalize(self, message: Any) -> bool:
142142
from openai.types.chat import ChatCompletion
143143

144144
return isinstance(message, ChatCompletion)
145-
except ImportError:
145+
except Exception:
146146
return False
147147

148148
def can_normalize_chunk(self, chunk: Any) -> bool:
149149
try:
150150
from openai.types.chat import ChatCompletionChunk
151151

152152
return isinstance(chunk, ChatCompletionChunk)
153-
except ImportError:
153+
except Exception:
154154
return False
155155

156156

157157
class AnthropicNormalizer(BaseMessageNormalizer):
158158
def normalize(self, message: Any) -> ChatMessage:
159159
x = cast("AnthropicMessage", message)
160-
content = x.content[0].text
161-
return ChatMessage(content=content, role="assistant")
160+
content = x.content[0]
161+
if content.type != "text":
162+
raise ValueError(
163+
f"Anthropic message type {content.type} not supported. "
164+
"Only 'text' type is supported"
165+
)
166+
return ChatMessage(content=content.text, role="assistant")
162167

163168
def normalize_chunk(self, chunk: Any) -> ChatMessageChunk:
164-
cnk = cast("MessageStreamEvent", chunk)
165-
content = cnk.delta.text if cnk.type == "content_block_delta" else ""
166-
type = "message_start" if cnk.type == "content_block_start" else "message_chunk"
169+
x = cast("MessageStreamEvent", chunk)
170+
content = ""
171+
if x.type == "content_block_delta":
172+
if x.delta.type != "text_delta":
173+
raise ValueError(
174+
f"Anthropic message delta type {x.delta.type} not supported. "
175+
"Only 'text_delta' type is supported"
176+
)
177+
content = x.delta.text
178+
179+
type = "message_start" if x.type == "content_block_start" else "message_chunk"
167180
return ChatMessageChunk(content=content, type=type, role="assistant")
168181

169182
def can_normalize(self, message: Any) -> bool:
170183
try:
171184
from anthropic.types import Message as AnthropicMessage
172185

173186
return isinstance(message, AnthropicMessage)
174-
except ImportError:
187+
except Exception:
175188
return False
176189

177190
def can_normalize_chunk(self, chunk: Any) -> bool:
178191
try:
179-
from anthropic.types import MessageStreamEvent
192+
from anthropic.types import (
193+
RawContentBlockDeltaEvent,
194+
RawContentBlockStartEvent,
195+
RawContentBlockStopEvent,
196+
RawMessageDeltaEvent,
197+
RawMessageStartEvent,
198+
RawMessageStopEvent,
199+
)
200+
201+
# The actual MessageStreamEvent is a generic, so isinstance() can't
202+
# be used to check the type. Instead, we manually construct the relevant
203+
# union of relevant classes...
204+
MessageStreamEvent = Union[
205+
RawMessageStartEvent,
206+
RawMessageDeltaEvent,
207+
RawMessageStopEvent,
208+
RawContentBlockStartEvent,
209+
RawContentBlockDeltaEvent,
210+
RawContentBlockStopEvent,
211+
]
180212

181213
return isinstance(chunk, MessageStreamEvent)
182-
except ImportError:
214+
except Exception:
183215
return False
184216

185217

@@ -199,7 +231,7 @@ def can_normalize(self, message: Any) -> bool:
199231
)
200232

201233
return isinstance(message, GenerateContentResponse)
202-
except ImportError:
234+
except Exception:
203235
return False
204236

205237
def can_normalize_chunk(self, chunk: Any) -> bool:

0 commit comments

Comments
 (0)