livekit-plugins-anthropic 0.2.0__py3-none-any.whl → 0.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- livekit/plugins/anthropic/llm.py +53 -35
- livekit/plugins/anthropic/version.py +1 -1
- {livekit_plugins_anthropic-0.2.0.dist-info → livekit_plugins_anthropic-0.2.1.dist-info}/METADATA +1 -1
- livekit_plugins_anthropic-0.2.1.dist-info/RECORD +10 -0
- livekit_plugins_anthropic-0.2.0.dist-info/RECORD +0 -10
- {livekit_plugins_anthropic-0.2.0.dist-info → livekit_plugins_anthropic-0.2.1.dist-info}/WHEEL +0 -0
- {livekit_plugins_anthropic-0.2.0.dist-info → livekit_plugins_anthropic-0.2.1.dist-info}/top_level.txt +0 -0
livekit/plugins/anthropic/llm.py
CHANGED
@@ -43,7 +43,7 @@ class LLM(llm.LLM):
|
|
43
43
|
def __init__(
|
44
44
|
self,
|
45
45
|
*,
|
46
|
-
model: str | ChatModels = "claude-3-
|
46
|
+
model: str | ChatModels = "claude-3-haiku-20240307",
|
47
47
|
api_key: str | None = None,
|
48
48
|
base_url: str | None = None,
|
49
49
|
user: str | None = None,
|
@@ -144,6 +144,9 @@ class LLMStream(llm.LLMStream):
|
|
144
144
|
if not self._anthropic_stream:
|
145
145
|
self._anthropic_stream = await self._awaitable_anthropic_stream
|
146
146
|
|
147
|
+
fn_calling_enabled = self._fnc_ctx is not None
|
148
|
+
ignore = False
|
149
|
+
|
147
150
|
async for event in self._anthropic_stream:
|
148
151
|
if event.type == "message_start":
|
149
152
|
pass
|
@@ -159,18 +162,34 @@ class LLMStream(llm.LLMStream):
|
|
159
162
|
elif event.type == "content_block_delta":
|
160
163
|
delta = event.delta
|
161
164
|
if delta.type == "text_delta":
|
165
|
+
text = delta.text
|
166
|
+
|
167
|
+
# Anthropic seems to add a prompt when tool calling is enabled
|
168
|
+
# where responses always start with a "<thinking>" block containing
|
169
|
+
# the LLM's chain of thought. It's very verbose and not useful for voice
|
170
|
+
# applications.
|
171
|
+
if fn_calling_enabled:
|
172
|
+
if text.startswith("<thinking>"):
|
173
|
+
ignore = True
|
174
|
+
|
175
|
+
if "</thinking>" in text:
|
176
|
+
text = text.split("</thinking>")[-1]
|
177
|
+
ignore = False
|
178
|
+
|
179
|
+
if ignore:
|
180
|
+
continue
|
181
|
+
|
162
182
|
return llm.ChatChunk(
|
163
183
|
choices=[
|
164
184
|
llm.Choice(
|
165
|
-
delta=llm.ChoiceDelta(
|
166
|
-
content=delta.text, role="assistant"
|
167
|
-
)
|
185
|
+
delta=llm.ChoiceDelta(content=text, role="assistant")
|
168
186
|
)
|
169
187
|
]
|
170
188
|
)
|
171
189
|
elif delta.type == "input_json_delta":
|
172
190
|
assert self._fnc_raw_arguments is not None
|
173
191
|
self._fnc_raw_arguments += delta.partial_json
|
192
|
+
|
174
193
|
elif event.type == "content_block_stop":
|
175
194
|
if self._tool_call_id is not None and self._fnc_ctx:
|
176
195
|
assert self._fnc_name is not None
|
@@ -249,13 +268,15 @@ def _build_anthropic_context(
|
|
249
268
|
) -> List[anthropic.types.MessageParam]:
|
250
269
|
result: List[anthropic.types.MessageParam] = []
|
251
270
|
for msg in chat_ctx:
|
252
|
-
a_msg = _build_anthropic_message(msg, cache_key)
|
271
|
+
a_msg = _build_anthropic_message(msg, cache_key, chat_ctx)
|
253
272
|
if a_msg:
|
254
273
|
result.append(a_msg)
|
255
274
|
return result
|
256
275
|
|
257
276
|
|
258
|
-
def _build_anthropic_message(
|
277
|
+
def _build_anthropic_message(
|
278
|
+
msg: llm.ChatMessage, cache_key: Any, chat_ctx: List[llm.ChatMessage]
|
279
|
+
) -> anthropic.types.MessageParam | None:
|
259
280
|
if msg.role == "user" or msg.role == "assistant":
|
260
281
|
a_msg: anthropic.types.MessageParam = {
|
261
282
|
"role": msg.role,
|
@@ -282,38 +303,35 @@ def _build_anthropic_message(msg: llm.ChatMessage, cache_key: Any):
|
|
282
303
|
a_content.append(content)
|
283
304
|
elif isinstance(cnt, llm.ChatImage):
|
284
305
|
a_content.append(_build_anthropic_image_content(cnt, cache_key))
|
285
|
-
|
286
|
-
elif msg.role == "tool":
|
287
|
-
ant_msg: anthropic.types.MessageParam = {
|
288
|
-
"role": "assistant",
|
289
|
-
"content": [],
|
290
|
-
}
|
291
|
-
assert isinstance(ant_msg["content"], list)
|
292
|
-
# make sure to provide when function has been called inside the context
|
293
|
-
# (+ raw_arguments)
|
306
|
+
|
294
307
|
if msg.tool_calls is not None:
|
295
308
|
for fnc in msg.tool_calls:
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
"name": fnc.function_info.name,
|
302
|
-
}
|
309
|
+
tool_use = anthropic.types.ToolUseBlockParam(
|
310
|
+
id=fnc.tool_call_id,
|
311
|
+
type="tool_use",
|
312
|
+
name=fnc.function_info.name,
|
313
|
+
input=fnc.arguments,
|
303
314
|
)
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
315
|
+
a_content.append(tool_use)
|
316
|
+
|
317
|
+
return a_msg
|
318
|
+
elif msg.role == "tool":
|
319
|
+
if not isinstance(msg.content, str):
|
320
|
+
logger.warning("tool message content is not a string")
|
321
|
+
return None
|
322
|
+
if not msg.tool_call_id:
|
323
|
+
return None
|
324
|
+
|
325
|
+
u_content = anthropic.types.ToolResultBlockParam(
|
326
|
+
tool_use_id=msg.tool_call_id,
|
327
|
+
type="tool_result",
|
328
|
+
content=msg.content,
|
329
|
+
is_error=msg.tool_exception is not None,
|
330
|
+
)
|
331
|
+
return {
|
332
|
+
"role": "user",
|
333
|
+
"content": [u_content],
|
334
|
+
}
|
317
335
|
|
318
336
|
return None
|
319
337
|
|
@@ -0,0 +1,10 @@
|
|
1
|
+
livekit/plugins/anthropic/__init__.py,sha256=g6KUqOfZo9DIBwBD98u6QOWY7pr8ZYJJ61fk3AWpoa4,1006
|
2
|
+
livekit/plugins/anthropic/llm.py,sha256=s6Xt_5kuvypG1ZLUq_aYaYO_ZaTgagyM4b1c5iI2WUo,17652
|
3
|
+
livekit/plugins/anthropic/log.py,sha256=fG1pYSY88AnT738gZrmzF9FO4l4BdGENj3VKHMQB3Yo,72
|
4
|
+
livekit/plugins/anthropic/models.py,sha256=AVEhrEtKfWxsd-R03u7R74hcKjJq4oDVSTukvoPQGb0,179
|
5
|
+
livekit/plugins/anthropic/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
6
|
+
livekit/plugins/anthropic/version.py,sha256=tb-eucPKT0bz3vQDaI1ltUZEhGKRFOFhN3U5ZIv_-xY,600
|
7
|
+
livekit_plugins_anthropic-0.2.1.dist-info/METADATA,sha256=-m1Q9gn3H1gRoVjFb1uIDfyJ5TP6p1HEMrh-zDyGeQs,1264
|
8
|
+
livekit_plugins_anthropic-0.2.1.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
|
9
|
+
livekit_plugins_anthropic-0.2.1.dist-info/top_level.txt,sha256=OoDok3xUmXbZRvOrfvvXB-Juu4DX79dlq188E19YHoo,8
|
10
|
+
livekit_plugins_anthropic-0.2.1.dist-info/RECORD,,
|
@@ -1,10 +0,0 @@
|
|
1
|
-
livekit/plugins/anthropic/__init__.py,sha256=g6KUqOfZo9DIBwBD98u6QOWY7pr8ZYJJ61fk3AWpoa4,1006
|
2
|
-
livekit/plugins/anthropic/llm.py,sha256=SJo_opc9_2rKYvcDW8-ltuOD-p7QUc0oROGDHu04htY,17162
|
3
|
-
livekit/plugins/anthropic/log.py,sha256=fG1pYSY88AnT738gZrmzF9FO4l4BdGENj3VKHMQB3Yo,72
|
4
|
-
livekit/plugins/anthropic/models.py,sha256=AVEhrEtKfWxsd-R03u7R74hcKjJq4oDVSTukvoPQGb0,179
|
5
|
-
livekit/plugins/anthropic/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
6
|
-
livekit/plugins/anthropic/version.py,sha256=cLFCdnm5S21CiJ5UJBcqfRvvFkCQ8p6M5fFUJVJkEiM,600
|
7
|
-
livekit_plugins_anthropic-0.2.0.dist-info/METADATA,sha256=1VWzsOFCxwtoB2m-NVZgKPoPI8xwsZctTbZJO8FYxbI,1264
|
8
|
-
livekit_plugins_anthropic-0.2.0.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
|
9
|
-
livekit_plugins_anthropic-0.2.0.dist-info/top_level.txt,sha256=OoDok3xUmXbZRvOrfvvXB-Juu4DX79dlq188E19YHoo,8
|
10
|
-
livekit_plugins_anthropic-0.2.0.dist-info/RECORD,,
|
{livekit_plugins_anthropic-0.2.0.dist-info → livekit_plugins_anthropic-0.2.1.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|