vectorvein 0.2.95__py3-none-any.whl → 0.2.97__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.
- vectorvein/chat_clients/anthropic_client.py +6 -18
- vectorvein/chat_clients/openai_compatible_client.py +243 -83
- {vectorvein-0.2.95.dist-info → vectorvein-0.2.97.dist-info}/METADATA +1 -1
- {vectorvein-0.2.95.dist-info → vectorvein-0.2.97.dist-info}/RECORD +6 -6
- {vectorvein-0.2.95.dist-info → vectorvein-0.2.97.dist-info}/WHEEL +0 -0
- {vectorvein-0.2.95.dist-info → vectorvein-0.2.97.dist-info}/entry_points.txt +0 -0
@@ -597,9 +597,7 @@ class AnthropicChatClient(BaseChatClient):
|
|
597
597
|
if max_tokens is None:
|
598
598
|
max_output_tokens = self.model_setting.max_output_tokens
|
599
599
|
native_multimodal = self.model_setting.native_multimodal
|
600
|
-
token_counts = get_message_token_counts(
|
601
|
-
messages=messages, tools=tools, model=self.model, native_multimodal=native_multimodal
|
602
|
-
)
|
600
|
+
token_counts = get_message_token_counts(messages=messages, tools=tools, model=self.model, native_multimodal=native_multimodal)
|
603
601
|
if max_output_tokens is not None:
|
604
602
|
max_tokens = self.model_setting.context_length - token_counts
|
605
603
|
max_tokens = min(max(max_tokens, 1), max_output_tokens)
|
@@ -707,9 +705,7 @@ class AnthropicChatClient(BaseChatClient):
|
|
707
705
|
result["raw_content"][i]["input"] = {}
|
708
706
|
try:
|
709
707
|
if result["tool_calls"][0]["function"]["arguments"]:
|
710
|
-
result["raw_content"][i]["input"] = json.loads(
|
711
|
-
result["tool_calls"][0]["function"]["arguments"]
|
712
|
-
)
|
708
|
+
result["raw_content"][i]["input"] = json.loads(result["tool_calls"][0]["function"]["arguments"])
|
713
709
|
else:
|
714
710
|
result["raw_content"][i]["input"] = {}
|
715
711
|
except json.JSONDecodeError:
|
@@ -727,9 +723,7 @@ class AnthropicChatClient(BaseChatClient):
|
|
727
723
|
yield ChatCompletionDeltaMessage(**message)
|
728
724
|
elif isinstance(chunk, RawMessageDeltaEvent):
|
729
725
|
result["usage"]["completion_tokens"] = chunk.usage.output_tokens
|
730
|
-
result["usage"]["total_tokens"] =
|
731
|
-
result["usage"]["prompt_tokens"] + result["usage"]["completion_tokens"]
|
732
|
-
)
|
726
|
+
result["usage"]["total_tokens"] = result["usage"]["prompt_tokens"] + result["usage"]["completion_tokens"]
|
733
727
|
yield ChatCompletionDeltaMessage(
|
734
728
|
usage=Usage(
|
735
729
|
prompt_tokens=result["usage"]["prompt_tokens"],
|
@@ -1211,9 +1205,7 @@ class AsyncAnthropicChatClient(BaseAsyncChatClient):
|
|
1211
1205
|
if max_tokens is None:
|
1212
1206
|
max_output_tokens = self.model_setting.max_output_tokens
|
1213
1207
|
native_multimodal = self.model_setting.native_multimodal
|
1214
|
-
token_counts = get_message_token_counts(
|
1215
|
-
messages=messages, tools=tools, model=self.model, native_multimodal=native_multimodal
|
1216
|
-
)
|
1208
|
+
token_counts = get_message_token_counts(messages=messages, tools=tools, model=self.model, native_multimodal=native_multimodal)
|
1217
1209
|
if max_output_tokens is not None:
|
1218
1210
|
max_tokens = self.model_setting.context_length - token_counts
|
1219
1211
|
max_tokens = min(max(max_tokens, 1), max_output_tokens)
|
@@ -1321,9 +1313,7 @@ class AsyncAnthropicChatClient(BaseAsyncChatClient):
|
|
1321
1313
|
result["raw_content"][i]["input"] = {}
|
1322
1314
|
try:
|
1323
1315
|
if result["tool_calls"][0]["function"]["arguments"]:
|
1324
|
-
result["raw_content"][i]["input"] = json.loads(
|
1325
|
-
result["tool_calls"][0]["function"]["arguments"]
|
1326
|
-
)
|
1316
|
+
result["raw_content"][i]["input"] = json.loads(result["tool_calls"][0]["function"]["arguments"])
|
1327
1317
|
else:
|
1328
1318
|
result["raw_content"][i]["input"] = {}
|
1329
1319
|
except json.JSONDecodeError:
|
@@ -1341,9 +1331,7 @@ class AsyncAnthropicChatClient(BaseAsyncChatClient):
|
|
1341
1331
|
yield ChatCompletionDeltaMessage(**message)
|
1342
1332
|
elif isinstance(chunk, RawMessageDeltaEvent):
|
1343
1333
|
result["usage"]["completion_tokens"] = chunk.usage.output_tokens
|
1344
|
-
result["usage"]["total_tokens"] =
|
1345
|
-
result["usage"]["prompt_tokens"] + result["usage"]["completion_tokens"]
|
1346
|
-
)
|
1334
|
+
result["usage"]["total_tokens"] = result["usage"]["prompt_tokens"] + result["usage"]["completion_tokens"]
|
1347
1335
|
yield ChatCompletionDeltaMessage(
|
1348
1336
|
usage=Usage(
|
1349
1337
|
prompt_tokens=result["usage"]["prompt_tokens"],
|
@@ -381,8 +381,8 @@ class OpenAICompatibleChatClient(BaseChatClient):
|
|
381
381
|
usage = None
|
382
382
|
buffer = ""
|
383
383
|
in_reasoning = False
|
384
|
-
|
385
|
-
|
384
|
+
accumulated_reasoning = []
|
385
|
+
accumulated_content = []
|
386
386
|
|
387
387
|
for chunk in stream_response:
|
388
388
|
if chunk.usage and chunk.usage.total_tokens:
|
@@ -404,63 +404,142 @@ class OpenAICompatibleChatClient(BaseChatClient):
|
|
404
404
|
for index, tool_call in enumerate(chunk.choices[0].delta.tool_calls):
|
405
405
|
tool_call.index = index
|
406
406
|
tool_call.type = "function" # 也是 MiniMax 的不规范导致的问题
|
407
|
-
|
407
|
+
|
408
|
+
# 即使支持 function call,也要处理 <think> 标签
|
409
|
+
message = chunk.choices[0].delta.model_dump()
|
410
|
+
delta_content = message.get("content", "")
|
411
|
+
if delta_content:
|
412
|
+
buffer += delta_content
|
413
|
+
|
414
|
+
# 处理缓冲区中的内容,提取 <think> 标签
|
415
|
+
current_output_content = ""
|
416
|
+
current_reasoning_content = ""
|
417
|
+
|
418
|
+
while buffer:
|
419
|
+
if not in_reasoning:
|
420
|
+
start_pos = buffer.find("<think>")
|
421
|
+
if start_pos != -1:
|
422
|
+
# 找到了 <think> 标签的开始
|
423
|
+
if start_pos > 0:
|
424
|
+
current_output_content += buffer[:start_pos]
|
425
|
+
buffer = buffer[start_pos + 7 :] # 跳过 "<think>"
|
426
|
+
in_reasoning = True
|
427
|
+
else:
|
428
|
+
# 没有找到 <think> 标签,直接输出
|
429
|
+
current_output_content += buffer
|
430
|
+
buffer = ""
|
431
|
+
else:
|
432
|
+
end_pos = buffer.find("</think>")
|
433
|
+
if end_pos != -1:
|
434
|
+
# 找到了 </think> 标签的结束
|
435
|
+
current_reasoning_content += buffer[:end_pos]
|
436
|
+
buffer = buffer[end_pos + 8 :] # 跳过 "</think>"
|
437
|
+
in_reasoning = False
|
438
|
+
else:
|
439
|
+
# 没有找到结束标签,继续累积到推理内容中
|
440
|
+
current_reasoning_content += buffer
|
441
|
+
buffer = ""
|
442
|
+
|
443
|
+
# 累积内容
|
444
|
+
if current_output_content:
|
445
|
+
accumulated_content.append(current_output_content)
|
446
|
+
if current_reasoning_content:
|
447
|
+
accumulated_reasoning.append(current_reasoning_content)
|
448
|
+
|
449
|
+
# 只要有内容变化就产生 delta
|
450
|
+
if current_output_content or current_reasoning_content:
|
451
|
+
if current_output_content:
|
452
|
+
message["content"] = current_output_content
|
453
|
+
elif current_reasoning_content:
|
454
|
+
message["reasoning_content"] = current_reasoning_content
|
455
|
+
message["content"] = "" # 推理时不输出普通内容
|
456
|
+
elif not current_output_content and not current_reasoning_content and not message.get("tool_calls"):
|
457
|
+
# 如果没有任何内容且没有 tool_calls,则跳过这个消息
|
458
|
+
continue
|
459
|
+
|
460
|
+
yield ChatCompletionDeltaMessage(**message, usage=usage)
|
408
461
|
else:
|
409
462
|
message = chunk.choices[0].delta.model_dump()
|
410
463
|
delta_content = message.get("content", "")
|
411
|
-
|
464
|
+
if delta_content:
|
465
|
+
buffer += delta_content
|
412
466
|
|
413
|
-
|
467
|
+
# 处理缓冲区中的内容,提取 <think> 标签
|
468
|
+
current_output_content = ""
|
469
|
+
current_reasoning_content = ""
|
470
|
+
|
471
|
+
while buffer:
|
414
472
|
if not in_reasoning:
|
415
473
|
start_pos = buffer.find("<think>")
|
416
474
|
if start_pos != -1:
|
417
|
-
|
418
|
-
|
475
|
+
# 找到了 <think> 标签的开始
|
476
|
+
if start_pos > 0:
|
477
|
+
current_output_content += buffer[:start_pos]
|
478
|
+
buffer = buffer[start_pos + 7 :] # 跳过 "<think>"
|
419
479
|
in_reasoning = True
|
420
480
|
else:
|
421
|
-
|
481
|
+
# 没有找到 <think> 标签,直接输出
|
482
|
+
current_output_content += buffer
|
422
483
|
buffer = ""
|
423
|
-
break
|
424
484
|
else:
|
425
485
|
end_pos = buffer.find("</think>")
|
426
486
|
if end_pos != -1:
|
427
|
-
|
428
|
-
|
487
|
+
# 找到了 </think> 标签的结束
|
488
|
+
current_reasoning_content += buffer[:end_pos]
|
489
|
+
buffer = buffer[end_pos + 8 :] # 跳过 "</think>"
|
429
490
|
in_reasoning = False
|
430
491
|
else:
|
431
|
-
|
492
|
+
# 没有找到结束标签,继续累积到推理内容中
|
493
|
+
current_reasoning_content += buffer
|
432
494
|
buffer = ""
|
433
|
-
break
|
434
|
-
|
435
|
-
message["content"] = "".join(current_content)
|
436
|
-
if current_reasoning:
|
437
|
-
message["reasoning_content"] = "".join(current_reasoning)
|
438
|
-
current_content.clear()
|
439
|
-
current_reasoning.clear()
|
440
|
-
|
441
|
-
if tools:
|
442
|
-
full_content += message["content"]
|
443
|
-
tool_call_data = ToolCallContentProcessor(full_content).tool_calls
|
444
|
-
if tool_call_data:
|
445
|
-
message["tool_calls"] = tool_call_data["tool_calls"]
|
446
|
-
|
447
|
-
if full_content in ("<", "<|", "<|▶", "<|▶|") or full_content.startswith("<|▶|>"):
|
448
|
-
message["content"] = ""
|
449
|
-
result = message
|
450
|
-
continue
|
451
|
-
|
452
|
-
yield ChatCompletionDeltaMessage(**message, usage=usage)
|
453
495
|
|
496
|
+
# 累积内容
|
497
|
+
if current_output_content:
|
498
|
+
accumulated_content.append(current_output_content)
|
499
|
+
if current_reasoning_content:
|
500
|
+
accumulated_reasoning.append(current_reasoning_content)
|
501
|
+
|
502
|
+
# 只要有内容变化就产生 delta
|
503
|
+
if current_output_content or current_reasoning_content:
|
504
|
+
if current_output_content:
|
505
|
+
message["content"] = current_output_content
|
506
|
+
elif current_reasoning_content:
|
507
|
+
message["reasoning_content"] = current_reasoning_content
|
508
|
+
message["content"] = "" # 推理时不输出普通内容
|
509
|
+
|
510
|
+
if tools:
|
511
|
+
full_content += current_output_content
|
512
|
+
tool_call_data = ToolCallContentProcessor(full_content).tool_calls
|
513
|
+
if tool_call_data:
|
514
|
+
message["tool_calls"] = tool_call_data["tool_calls"]
|
515
|
+
|
516
|
+
if full_content in ("<", "<|", "<|▶", "<|▶|") or full_content.startswith("<|▶|>"):
|
517
|
+
message["content"] = ""
|
518
|
+
result = message
|
519
|
+
continue
|
520
|
+
|
521
|
+
yield ChatCompletionDeltaMessage(**message, usage=usage)
|
522
|
+
|
523
|
+
# 处理最后剩余的缓冲区内容
|
454
524
|
if buffer:
|
455
525
|
if in_reasoning:
|
456
|
-
|
526
|
+
accumulated_reasoning.append(buffer)
|
457
527
|
else:
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
528
|
+
accumulated_content.append(buffer)
|
529
|
+
|
530
|
+
final_message = {}
|
531
|
+
if accumulated_content:
|
532
|
+
final_content = "".join(accumulated_content)
|
533
|
+
if final_content.strip(): # 只有当内容非空时才输出
|
534
|
+
final_message["content"] = final_content
|
535
|
+
|
536
|
+
if accumulated_reasoning:
|
537
|
+
final_reasoning = "".join(accumulated_reasoning)
|
538
|
+
if final_reasoning.strip(): # 只有当推理内容非空时才输出
|
539
|
+
final_message["reasoning_content"] = final_reasoning
|
540
|
+
|
541
|
+
if final_message:
|
542
|
+
yield ChatCompletionDeltaMessage(**final_message, usage=usage)
|
464
543
|
|
465
544
|
if result:
|
466
545
|
yield ChatCompletionDeltaMessage(**result, usage=usage)
|
@@ -517,8 +596,9 @@ class OpenAICompatibleChatClient(BaseChatClient):
|
|
517
596
|
result["content"] = result["content"].replace(think_match.group(0), "", 1)
|
518
597
|
|
519
598
|
if tools:
|
520
|
-
if self.model_setting.function_call_available
|
521
|
-
|
599
|
+
if self.model_setting.function_call_available:
|
600
|
+
if response.choices[0].message.tool_calls:
|
601
|
+
result["tool_calls"] = [{**tool_call.model_dump(), "type": "function"} for tool_call in response.choices[0].message.tool_calls]
|
522
602
|
else:
|
523
603
|
tool_call_content_processor = ToolCallContentProcessor(result["content"])
|
524
604
|
tool_call_data = tool_call_content_processor.tool_calls
|
@@ -819,7 +899,7 @@ class AsyncOpenAICompatibleChatClient(BaseAsyncChatClient):
|
|
819
899
|
messages=messages,
|
820
900
|
stream=self.stream,
|
821
901
|
temperature=self.temperature,
|
822
|
-
max_tokens=max_tokens,
|
902
|
+
max_tokens=max_tokens,
|
823
903
|
top_p=top_p,
|
824
904
|
audio=audio,
|
825
905
|
frequency_penalty=frequency_penalty,
|
@@ -854,8 +934,8 @@ class AsyncOpenAICompatibleChatClient(BaseAsyncChatClient):
|
|
854
934
|
usage = None
|
855
935
|
buffer = ""
|
856
936
|
in_reasoning = False
|
857
|
-
|
858
|
-
|
937
|
+
accumulated_reasoning = []
|
938
|
+
accumulated_content = []
|
859
939
|
|
860
940
|
async for chunk in stream_response:
|
861
941
|
if chunk.usage and chunk.usage.total_tokens:
|
@@ -877,63 +957,142 @@ class AsyncOpenAICompatibleChatClient(BaseAsyncChatClient):
|
|
877
957
|
for index, tool_call in enumerate(chunk.choices[0].delta.tool_calls):
|
878
958
|
tool_call.index = index
|
879
959
|
tool_call.type = "function"
|
880
|
-
|
960
|
+
|
961
|
+
# 即使支持 function call,也要处理 <think> 标签
|
962
|
+
message = chunk.choices[0].delta.model_dump()
|
963
|
+
delta_content = message.get("content", "")
|
964
|
+
if delta_content:
|
965
|
+
buffer += delta_content
|
966
|
+
|
967
|
+
# 处理缓冲区中的内容,提取 <think> 标签
|
968
|
+
current_output_content = ""
|
969
|
+
current_reasoning_content = ""
|
970
|
+
|
971
|
+
while buffer:
|
972
|
+
if not in_reasoning:
|
973
|
+
start_pos = buffer.find("<think>")
|
974
|
+
if start_pos != -1:
|
975
|
+
# 找到了 <think> 标签的开始
|
976
|
+
if start_pos > 0:
|
977
|
+
current_output_content += buffer[:start_pos]
|
978
|
+
buffer = buffer[start_pos + 7 :] # 跳过 "<think>"
|
979
|
+
in_reasoning = True
|
980
|
+
else:
|
981
|
+
# 没有找到 <think> 标签,直接输出
|
982
|
+
current_output_content += buffer
|
983
|
+
buffer = ""
|
984
|
+
else:
|
985
|
+
end_pos = buffer.find("</think>")
|
986
|
+
if end_pos != -1:
|
987
|
+
# 找到了 </think> 标签的结束
|
988
|
+
current_reasoning_content += buffer[:end_pos]
|
989
|
+
buffer = buffer[end_pos + 8 :] # 跳过 "</think>"
|
990
|
+
in_reasoning = False
|
991
|
+
else:
|
992
|
+
# 没有找到结束标签,继续累积到推理内容中
|
993
|
+
current_reasoning_content += buffer
|
994
|
+
buffer = ""
|
995
|
+
|
996
|
+
# 累积内容
|
997
|
+
if current_output_content:
|
998
|
+
accumulated_content.append(current_output_content)
|
999
|
+
if current_reasoning_content:
|
1000
|
+
accumulated_reasoning.append(current_reasoning_content)
|
1001
|
+
|
1002
|
+
# 只要有内容变化就产生 delta
|
1003
|
+
if current_output_content or current_reasoning_content:
|
1004
|
+
if current_output_content:
|
1005
|
+
message["content"] = current_output_content
|
1006
|
+
elif current_reasoning_content:
|
1007
|
+
message["reasoning_content"] = current_reasoning_content
|
1008
|
+
message["content"] = "" # 推理时不输出普通内容
|
1009
|
+
elif not current_output_content and not current_reasoning_content and not message.get("tool_calls"):
|
1010
|
+
# 如果没有任何内容且没有 tool_calls,则跳过这个消息
|
1011
|
+
continue
|
1012
|
+
|
1013
|
+
yield ChatCompletionDeltaMessage(**message, usage=usage)
|
881
1014
|
else:
|
882
1015
|
message = chunk.choices[0].delta.model_dump()
|
883
1016
|
delta_content = message.get("content", "")
|
884
|
-
|
1017
|
+
if delta_content:
|
1018
|
+
buffer += delta_content
|
885
1019
|
|
886
|
-
|
1020
|
+
# 处理缓冲区中的内容,提取 <think> 标签
|
1021
|
+
current_output_content = ""
|
1022
|
+
current_reasoning_content = ""
|
1023
|
+
|
1024
|
+
while buffer:
|
887
1025
|
if not in_reasoning:
|
888
1026
|
start_pos = buffer.find("<think>")
|
889
1027
|
if start_pos != -1:
|
890
|
-
|
891
|
-
|
1028
|
+
# 找到了 <think> 标签的开始
|
1029
|
+
if start_pos > 0:
|
1030
|
+
current_output_content += buffer[:start_pos]
|
1031
|
+
buffer = buffer[start_pos + 7 :] # 跳过 "<think>"
|
892
1032
|
in_reasoning = True
|
893
1033
|
else:
|
894
|
-
|
1034
|
+
# 没有找到 <think> 标签,直接输出
|
1035
|
+
current_output_content += buffer
|
895
1036
|
buffer = ""
|
896
|
-
break
|
897
1037
|
else:
|
898
1038
|
end_pos = buffer.find("</think>")
|
899
1039
|
if end_pos != -1:
|
900
|
-
|
901
|
-
|
1040
|
+
# 找到了 </think> 标签的结束
|
1041
|
+
current_reasoning_content += buffer[:end_pos]
|
1042
|
+
buffer = buffer[end_pos + 8 :] # 跳过 "</think>"
|
902
1043
|
in_reasoning = False
|
903
1044
|
else:
|
904
|
-
|
1045
|
+
# 没有找到结束标签,继续累积到推理内容中
|
1046
|
+
current_reasoning_content += buffer
|
905
1047
|
buffer = ""
|
906
|
-
break
|
907
|
-
|
908
|
-
message["content"] = "".join(current_content)
|
909
|
-
if current_reasoning:
|
910
|
-
message["reasoning_content"] = "".join(current_reasoning)
|
911
|
-
current_content.clear()
|
912
|
-
current_reasoning.clear()
|
913
|
-
|
914
|
-
if tools:
|
915
|
-
full_content += message["content"]
|
916
|
-
tool_call_data = ToolCallContentProcessor(full_content).tool_calls
|
917
|
-
if tool_call_data:
|
918
|
-
message["tool_calls"] = tool_call_data["tool_calls"]
|
919
|
-
|
920
|
-
if full_content in ("<", "<|", "<|▶", "<|▶|") or full_content.startswith("<|▶|>"):
|
921
|
-
message["content"] = ""
|
922
|
-
result = message
|
923
|
-
continue
|
924
|
-
|
925
|
-
yield ChatCompletionDeltaMessage(**message, usage=usage)
|
926
1048
|
|
1049
|
+
# 累积内容
|
1050
|
+
if current_output_content:
|
1051
|
+
accumulated_content.append(current_output_content)
|
1052
|
+
if current_reasoning_content:
|
1053
|
+
accumulated_reasoning.append(current_reasoning_content)
|
1054
|
+
|
1055
|
+
# 只要有内容变化就产生 delta
|
1056
|
+
if current_output_content or current_reasoning_content:
|
1057
|
+
if current_output_content:
|
1058
|
+
message["content"] = current_output_content
|
1059
|
+
elif current_reasoning_content:
|
1060
|
+
message["reasoning_content"] = current_reasoning_content
|
1061
|
+
message["content"] = "" # 推理时不输出普通内容
|
1062
|
+
|
1063
|
+
if tools:
|
1064
|
+
full_content += current_output_content
|
1065
|
+
tool_call_data = ToolCallContentProcessor(full_content).tool_calls
|
1066
|
+
if tool_call_data:
|
1067
|
+
message["tool_calls"] = tool_call_data["tool_calls"]
|
1068
|
+
|
1069
|
+
if full_content in ("<", "<|", "<|▶", "<|▶|") or full_content.startswith("<|▶|>"):
|
1070
|
+
message["content"] = ""
|
1071
|
+
result = message
|
1072
|
+
continue
|
1073
|
+
|
1074
|
+
yield ChatCompletionDeltaMessage(**message, usage=usage)
|
1075
|
+
|
1076
|
+
# 处理最后剩余的缓冲区内容
|
927
1077
|
if buffer:
|
928
1078
|
if in_reasoning:
|
929
|
-
|
1079
|
+
accumulated_reasoning.append(buffer)
|
930
1080
|
else:
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
1081
|
+
accumulated_content.append(buffer)
|
1082
|
+
|
1083
|
+
final_message = {}
|
1084
|
+
if accumulated_content:
|
1085
|
+
final_content = "".join(accumulated_content)
|
1086
|
+
if final_content.strip(): # 只有当内容非空时才输出
|
1087
|
+
final_message["content"] = final_content
|
1088
|
+
|
1089
|
+
if accumulated_reasoning:
|
1090
|
+
final_reasoning = "".join(accumulated_reasoning)
|
1091
|
+
if final_reasoning.strip(): # 只有当推理内容非空时才输出
|
1092
|
+
final_message["reasoning_content"] = final_reasoning
|
1093
|
+
|
1094
|
+
if final_message:
|
1095
|
+
yield ChatCompletionDeltaMessage(**final_message, usage=usage)
|
937
1096
|
|
938
1097
|
if result:
|
939
1098
|
yield ChatCompletionDeltaMessage(**result, usage=usage)
|
@@ -990,8 +1149,9 @@ class AsyncOpenAICompatibleChatClient(BaseAsyncChatClient):
|
|
990
1149
|
result["content"] = result["content"].replace(think_match.group(0), "", 1)
|
991
1150
|
|
992
1151
|
if tools:
|
993
|
-
if self.model_setting.function_call_available
|
994
|
-
|
1152
|
+
if self.model_setting.function_call_available:
|
1153
|
+
if response.choices[0].message.tool_calls:
|
1154
|
+
result["tool_calls"] = [{**tool_call.model_dump(), "type": "function"} for tool_call in response.choices[0].message.tool_calls]
|
995
1155
|
else:
|
996
1156
|
tool_call_content_processor = ToolCallContentProcessor(result["content"])
|
997
1157
|
tool_call_data = tool_call_content_processor.tool_calls
|
@@ -1,13 +1,13 @@
|
|
1
|
-
vectorvein-0.2.
|
2
|
-
vectorvein-0.2.
|
3
|
-
vectorvein-0.2.
|
1
|
+
vectorvein-0.2.97.dist-info/METADATA,sha256=F8G_9pNYMNCXCIo0SSfoV-D-DqPa_exIH6QQRW9h91c,4567
|
2
|
+
vectorvein-0.2.97.dist-info/WHEEL,sha256=tSfRZzRHthuv7vxpI4aehrdN9scLjk-dCJkPLzkHxGg,90
|
3
|
+
vectorvein-0.2.97.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
|
4
4
|
vectorvein/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
5
|
vectorvein/api/__init__.py,sha256=lfY-XA46fgD2iIZTU0VYP8i07AwA03Egj4Qua0vUKrQ,738
|
6
6
|
vectorvein/api/client.py,sha256=xF-leKDQzVyyy9FnIRaz0k4eElYW1XbbzeRLcpnyk90,33047
|
7
7
|
vectorvein/api/exceptions.py,sha256=uS_PAdx0ksC0r3dgfSGWdbLMZm4qdLeWSSqCv1g3_Gc,772
|
8
8
|
vectorvein/api/models.py,sha256=xtPWMsB0yIJI7i-gY4B6MtvXv0ZIXnoeKspmeInH6fU,1449
|
9
9
|
vectorvein/chat_clients/__init__.py,sha256=UIytpIgwo8qkZpIyrHVxLYTyliUOTp4J7C4iHRjbtWE,23850
|
10
|
-
vectorvein/chat_clients/anthropic_client.py,sha256=
|
10
|
+
vectorvein/chat_clients/anthropic_client.py,sha256=OYqPjRzFcwhZjHSxmj0NlfZSwsVAo_PPD5sCqnMMBHA,68874
|
11
11
|
vectorvein/chat_clients/baichuan_client.py,sha256=CVMvpgjdrZGv0BWnTOBD-f2ufZ3wq3496wqukumsAr4,526
|
12
12
|
vectorvein/chat_clients/base_client.py,sha256=p7s-G4Wh9MSpDKEfG8wuFAeWy5DGvj5Go31hqrpQPhM,38817
|
13
13
|
vectorvein/chat_clients/deepseek_client.py,sha256=3qWu01NlJAP2N-Ff62d5-CZXZitlizE1fzb20LNetig,526
|
@@ -19,7 +19,7 @@ vectorvein/chat_clients/minimax_client.py,sha256=YOILWcsHsN5tihLTMbKJIyJr9TJREMI
|
|
19
19
|
vectorvein/chat_clients/mistral_client.py,sha256=1aKSylzBDaLYcFnaBIL4-sXSzWmXfBeON9Q0rq-ziWw,534
|
20
20
|
vectorvein/chat_clients/moonshot_client.py,sha256=gbu-6nGxx8uM_U2WlI4Wus881rFRotzHtMSoYOcruGU,526
|
21
21
|
vectorvein/chat_clients/openai_client.py,sha256=Nz6tV45pWcsOupxjnsRsGTicbQNJWIZyxuJoJ5DGMpg,527
|
22
|
-
vectorvein/chat_clients/openai_compatible_client.py,sha256=
|
22
|
+
vectorvein/chat_clients/openai_compatible_client.py,sha256=p9jWjuNnrOg3-OwW_Q_1FjgtPHKsKL4_L3oD_7M7U2Y,58729
|
23
23
|
vectorvein/chat_clients/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
24
24
|
vectorvein/chat_clients/qwen_client.py,sha256=-ryh-m9PgsO0fc4ulcCmPTy1155J8YUy15uPoJQOHA0,513
|
25
25
|
vectorvein/chat_clients/stepfun_client.py,sha256=zsD2W5ahmR4DD9cqQTXmJr3txrGuvxbRWhFlRdwNijI,519
|
@@ -65,4 +65,4 @@ vectorvein/workflow/utils/analyse.py,sha256=msmvyz35UTYTwqQR5sg9H0sm1vxmGDSmep9X
|
|
65
65
|
vectorvein/workflow/utils/check.py,sha256=B_NdwqIqnc7Ko2HHqFpfOmWVaAu21tPITe0szKfiZKc,11414
|
66
66
|
vectorvein/workflow/utils/json_to_code.py,sha256=P8dhhSNgKhTnW17qXNjLO2aLdb0rA8qMAWxhObol2TU,7295
|
67
67
|
vectorvein/workflow/utils/layout.py,sha256=j0bRD3uaXu40xCS6U6BGahBI8FrHa5MiF55GbTrZ1LM,4565
|
68
|
-
vectorvein-0.2.
|
68
|
+
vectorvein-0.2.97.dist-info/RECORD,,
|
File without changes
|
File without changes
|