vectorvein 0.1.14__tar.gz → 0.1.16__tar.gz
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-0.1.14 → vectorvein-0.1.16}/PKG-INFO +1 -1
- {vectorvein-0.1.14 → vectorvein-0.1.16}/pyproject.toml +6 -1
- {vectorvein-0.1.14 → vectorvein-0.1.16}/src/vectorvein/chat_clients/__init__.py +2 -1
- {vectorvein-0.1.14 → vectorvein-0.1.16}/src/vectorvein/chat_clients/anthropic_client.py +3 -5
- {vectorvein-0.1.14 → vectorvein-0.1.16}/src/vectorvein/chat_clients/openai_compatible_client.py +3 -5
- {vectorvein-0.1.14 → vectorvein-0.1.16}/src/vectorvein/chat_clients/utils.py +41 -1
- {vectorvein-0.1.14 → vectorvein-0.1.16}/src/vectorvein/types/defaults.py +11 -0
- {vectorvein-0.1.14 → vectorvein-0.1.16}/src/vectorvein/types/llm_parameters.py +1 -0
- vectorvein-0.1.14/tests/__init__.py +0 -0
- vectorvein-0.1.14/tests/cat.png +0 -0
- vectorvein-0.1.14/tests/sample_settings.py +0 -614
- vectorvein-0.1.14/tests/test_chat_prefix.py +0 -23
- vectorvein-0.1.14/tests/test_create_chat_client.py +0 -234
- vectorvein-0.1.14/tests/test_format_messages.py +0 -41
- vectorvein-0.1.14/tests/test_http_client.py +0 -24
- vectorvein-0.1.14/tests/test_image_input_chat_client.py +0 -45
- vectorvein-0.1.14/tests/test_stop.py +0 -25
- vectorvein-0.1.14/tests/test_tokens_count.py +0 -46
- vectorvein-0.1.14/tests/test_tool_use_multi_turns.py +0 -159
- {vectorvein-0.1.14 → vectorvein-0.1.16}/README.md +0 -0
- {vectorvein-0.1.14 → vectorvein-0.1.16}/src/vectorvein/__init__.py +0 -0
- {vectorvein-0.1.14 → vectorvein-0.1.16}/src/vectorvein/chat_clients/baichuan_client.py +0 -0
- {vectorvein-0.1.14 → vectorvein-0.1.16}/src/vectorvein/chat_clients/base_client.py +0 -0
- {vectorvein-0.1.14 → vectorvein-0.1.16}/src/vectorvein/chat_clients/deepseek_client.py +0 -0
- {vectorvein-0.1.14 → vectorvein-0.1.16}/src/vectorvein/chat_clients/gemini_client.py +0 -0
- {vectorvein-0.1.14 → vectorvein-0.1.16}/src/vectorvein/chat_clients/groq_client.py +0 -0
- {vectorvein-0.1.14 → vectorvein-0.1.16}/src/vectorvein/chat_clients/local_client.py +0 -0
- {vectorvein-0.1.14 → vectorvein-0.1.16}/src/vectorvein/chat_clients/minimax_client.py +0 -0
- {vectorvein-0.1.14 → vectorvein-0.1.16}/src/vectorvein/chat_clients/mistral_client.py +0 -0
- {vectorvein-0.1.14 → vectorvein-0.1.16}/src/vectorvein/chat_clients/moonshot_client.py +0 -0
- {vectorvein-0.1.14 → vectorvein-0.1.16}/src/vectorvein/chat_clients/openai_client.py +0 -0
- {vectorvein-0.1.14 → vectorvein-0.1.16}/src/vectorvein/chat_clients/qwen_client.py +0 -0
- {vectorvein-0.1.14 → vectorvein-0.1.16}/src/vectorvein/chat_clients/yi_client.py +0 -0
- {vectorvein-0.1.14 → vectorvein-0.1.16}/src/vectorvein/chat_clients/zhipuai_client.py +0 -0
- {vectorvein-0.1.14 → vectorvein-0.1.16}/src/vectorvein/settings/__init__.py +0 -0
- {vectorvein-0.1.14 → vectorvein-0.1.16}/src/vectorvein/types/enums.py +0 -0
- {vectorvein-0.1.14 → vectorvein-0.1.16}/src/vectorvein/utilities/media_processing.py +0 -0
- {vectorvein-0.1.14 → vectorvein-0.1.16}/src/vectorvein/utilities/retry.py +0 -0
@@ -16,7 +16,7 @@ description = "Default template for PDM package"
|
|
16
16
|
name = "vectorvein"
|
17
17
|
readme = "README.md"
|
18
18
|
requires-python = ">=3.10"
|
19
|
-
version = "0.1.
|
19
|
+
version = "0.1.16"
|
20
20
|
|
21
21
|
[project.license]
|
22
22
|
text = "MIT"
|
@@ -29,3 +29,8 @@ requires = [
|
|
29
29
|
|
30
30
|
[tool.pdm]
|
31
31
|
distribution = true
|
32
|
+
|
33
|
+
[tool.pdm.build]
|
34
|
+
excludes = [
|
35
|
+
"tests",
|
36
|
+
]
|
@@ -20,7 +20,7 @@ from .deepseek_client import DeepSeekChatClient, AsyncDeepSeekChatClient
|
|
20
20
|
from ..types import defaults as defs
|
21
21
|
from ..types.enums import BackendType, ContextLengthControlType
|
22
22
|
from .anthropic_client import AnthropicChatClient, AsyncAnthropicChatClient
|
23
|
-
from .utils import format_messages, get_token_counts, ToolCallContentProcessor
|
23
|
+
from .utils import format_messages, get_token_counts, get_message_token_counts, ToolCallContentProcessor
|
24
24
|
|
25
25
|
|
26
26
|
BackendMap = {
|
@@ -125,5 +125,6 @@ __all__ = [
|
|
125
125
|
"get_token_counts",
|
126
126
|
"create_chat_client",
|
127
127
|
"create_async_chat_client",
|
128
|
+
"get_message_token_counts",
|
128
129
|
"ToolCallContentProcessor",
|
129
130
|
]
|
@@ -21,7 +21,7 @@ from google.auth import _helpers
|
|
21
21
|
|
22
22
|
from ..settings import settings
|
23
23
|
from ..types import defaults as defs
|
24
|
-
from .utils import cutoff_messages,
|
24
|
+
from .utils import cutoff_messages, get_message_token_counts
|
25
25
|
from .base_client import BaseChatClient, BaseAsyncChatClient
|
26
26
|
from ..types.enums import ContextLengthControlType, BackendType
|
27
27
|
from ..types.llm_parameters import ChatCompletionMessage, ChatCompletionDeltaMessage
|
@@ -199,12 +199,11 @@ class AnthropicChatClient(BaseChatClient):
|
|
199
199
|
|
200
200
|
if max_tokens is None:
|
201
201
|
max_output_tokens = self.model_setting.max_output_tokens
|
202
|
+
token_counts = get_message_token_counts(messages=messages, tools=tools_params, model=self.model_setting.id)
|
202
203
|
if max_output_tokens is not None:
|
203
|
-
token_counts = get_token_counts({"messages": messages, "tools_params": tools_params})
|
204
204
|
max_tokens = self.model_setting.context_length - token_counts
|
205
205
|
max_tokens = min(max(max_tokens, 1), max_output_tokens)
|
206
206
|
else:
|
207
|
-
token_counts = get_token_counts({"messages": messages, "tools_params": tools_params})
|
208
207
|
max_tokens = self.model_setting.context_length - token_counts
|
209
208
|
|
210
209
|
response = self._client.messages.create(
|
@@ -405,12 +404,11 @@ class AsyncAnthropicChatClient(BaseAsyncChatClient):
|
|
405
404
|
|
406
405
|
if max_tokens is None:
|
407
406
|
max_output_tokens = self.model_setting.max_output_tokens
|
407
|
+
token_counts = get_message_token_counts(messages=messages, tools=tools_params, model=self.model_setting.id)
|
408
408
|
if max_output_tokens is not None:
|
409
|
-
token_counts = get_token_counts({"messages": messages, "tools_params": tools_params})
|
410
409
|
max_tokens = self.model_setting.context_length - token_counts
|
411
410
|
max_tokens = min(max(max_tokens, 1), max_output_tokens)
|
412
411
|
else:
|
413
|
-
token_counts = get_token_counts({"messages": messages, "tools_params": tools_params})
|
414
412
|
max_tokens = self.model_setting.context_length - token_counts
|
415
413
|
|
416
414
|
response = await self._client.messages.create(
|
{vectorvein-0.1.14 → vectorvein-0.1.16}/src/vectorvein/chat_clients/openai_compatible_client.py
RENAMED
@@ -12,7 +12,7 @@ from openai import OpenAI, AsyncOpenAI, AzureOpenAI, AsyncAzureOpenAI
|
|
12
12
|
from .base_client import BaseChatClient, BaseAsyncChatClient
|
13
13
|
from .utils import (
|
14
14
|
cutoff_messages,
|
15
|
-
|
15
|
+
get_message_token_counts,
|
16
16
|
ToolCallContentProcessor,
|
17
17
|
generate_tool_use_system_prompt,
|
18
18
|
)
|
@@ -111,12 +111,11 @@ class OpenAICompatibleChatClient(BaseChatClient):
|
|
111
111
|
|
112
112
|
if max_tokens is None:
|
113
113
|
max_output_tokens = self.model_setting.max_output_tokens
|
114
|
+
token_counts = get_message_token_counts(messages=messages, tools=tools_params, model=self.model_setting.id)
|
114
115
|
if max_output_tokens is not None:
|
115
|
-
token_counts = get_token_counts({"messages": messages, "tools_params": tools_params})
|
116
116
|
max_tokens = self.model_setting.context_length - token_counts
|
117
117
|
max_tokens = min(max(max_tokens, 1), max_output_tokens)
|
118
118
|
else:
|
119
|
-
token_counts = get_token_counts({"messages": messages, "tools_params": tools_params})
|
120
119
|
max_tokens = self.model_setting.context_length - token_counts
|
121
120
|
|
122
121
|
response: ChatCompletion | Stream[ChatCompletionChunk] = self._client.chat.completions.create(
|
@@ -270,12 +269,11 @@ class AsyncOpenAICompatibleChatClient(BaseAsyncChatClient):
|
|
270
269
|
|
271
270
|
if max_tokens is None:
|
272
271
|
max_output_tokens = self.model_setting.max_output_tokens
|
272
|
+
token_counts = get_message_token_counts(messages=messages, tools=tools_params, model=self.model_setting.id)
|
273
273
|
if max_output_tokens is not None:
|
274
|
-
token_counts = get_token_counts({"messages": messages, "tools_params": tools_params})
|
275
274
|
max_tokens = self.model_setting.context_length - token_counts
|
276
275
|
max_tokens = min(max(max_tokens, 1), max_output_tokens)
|
277
276
|
else:
|
278
|
-
token_counts = get_token_counts({"messages": messages, "tools_params": tools_params})
|
279
277
|
max_tokens = self.model_setting.context_length - token_counts
|
280
278
|
|
281
279
|
response: ChatCompletion | AsyncStream[ChatCompletionChunk] = await self._client.chat.completions.create(
|
@@ -2,7 +2,7 @@
|
|
2
2
|
# @Date: 2024-07-26 14:48:55
|
3
3
|
import re
|
4
4
|
import json
|
5
|
-
|
5
|
+
from math import ceil
|
6
6
|
import httpx
|
7
7
|
import tiktoken
|
8
8
|
from anthropic import Anthropic
|
@@ -187,6 +187,46 @@ def get_token_counts(text: str | dict, model: str = "") -> int:
|
|
187
187
|
return len(chatgpt_encoding.encode(text))
|
188
188
|
|
189
189
|
|
190
|
+
def calculate_image_tokens(width: int, height: int, model: str = "gpt-4o"):
|
191
|
+
if width > 2048 or height > 2048:
|
192
|
+
aspect_ratio = width / height
|
193
|
+
if aspect_ratio > 1:
|
194
|
+
width, height = 2048, int(2048 / aspect_ratio)
|
195
|
+
else:
|
196
|
+
width, height = int(2048 * aspect_ratio), 2048
|
197
|
+
|
198
|
+
if width >= height and height > 768:
|
199
|
+
width, height = int((768 / height) * width), 768
|
200
|
+
elif height > width and width > 768:
|
201
|
+
width, height = 768, int((768 / width) * height)
|
202
|
+
|
203
|
+
tiles_width = ceil(width / 512)
|
204
|
+
tiles_height = ceil(height / 512)
|
205
|
+
total_tokens = 85 + 170 * (tiles_width * tiles_height)
|
206
|
+
|
207
|
+
return total_tokens
|
208
|
+
|
209
|
+
|
210
|
+
def get_message_token_counts(messages: list, tools: dict | None = None, model: str = "gpt-4o") -> int:
|
211
|
+
tokens = 0
|
212
|
+
formatted_messages = format_messages(messages, backend=BackendType.OpenAI, native_multimodal=True)
|
213
|
+
for message in formatted_messages:
|
214
|
+
content = message["content"]
|
215
|
+
if isinstance(content, str):
|
216
|
+
tokens += get_token_counts(content, model)
|
217
|
+
elif isinstance(content, list):
|
218
|
+
for item in content:
|
219
|
+
if isinstance(item, dict) and item["type"] == "text":
|
220
|
+
tokens += get_token_counts(item["text"], model)
|
221
|
+
elif isinstance(item, dict) and item["type"].startswith("image"):
|
222
|
+
# TODO: Get real image size
|
223
|
+
tokens += calculate_image_tokens(2048, 2048, model)
|
224
|
+
if tools is not None:
|
225
|
+
tokens += get_token_counts(json.dumps(tools, ensure_ascii=False), model)
|
226
|
+
|
227
|
+
return tokens
|
228
|
+
|
229
|
+
|
190
230
|
def cutoff_messages(
|
191
231
|
messages: list,
|
192
232
|
max_count: int = 16000,
|
@@ -233,6 +233,7 @@ YI_MODELS = {
|
|
233
233
|
"max_output_tokens": 2000,
|
234
234
|
"function_call_available": False,
|
235
235
|
"response_format_available": False,
|
236
|
+
"native_multimodal": True,
|
236
237
|
},
|
237
238
|
}
|
238
239
|
|
@@ -301,6 +302,7 @@ ZHIPUAI_MODELS = {
|
|
301
302
|
"function_call_available": False,
|
302
303
|
"response_format_available": False,
|
303
304
|
"max_output_tokens": 1024,
|
305
|
+
"native_multimodal": True,
|
304
306
|
},
|
305
307
|
"glm-4v-plus": {
|
306
308
|
"id": "glm-4v-plus",
|
@@ -308,6 +310,7 @@ ZHIPUAI_MODELS = {
|
|
308
310
|
"function_call_available": False,
|
309
311
|
"response_format_available": False,
|
310
312
|
"max_output_tokens": 1024,
|
313
|
+
"native_multimodal": True,
|
311
314
|
},
|
312
315
|
}
|
313
316
|
|
@@ -394,6 +397,7 @@ OPENAI_MODELS = {
|
|
394
397
|
"max_output_tokens": 4096,
|
395
398
|
"function_call_available": True,
|
396
399
|
"response_format_available": True,
|
400
|
+
"native_multimodal": True,
|
397
401
|
},
|
398
402
|
"gpt-4o-mini": {
|
399
403
|
"id": "gpt-4o-mini",
|
@@ -401,6 +405,7 @@ OPENAI_MODELS = {
|
|
401
405
|
"max_output_tokens": 16384,
|
402
406
|
"function_call_available": True,
|
403
407
|
"response_format_available": True,
|
408
|
+
"native_multimodal": True,
|
404
409
|
},
|
405
410
|
"gpt-4v": {
|
406
411
|
"id": "gpt-4v",
|
@@ -420,12 +425,14 @@ ANTHROPIC_MODELS = {
|
|
420
425
|
"max_output_tokens": 4096,
|
421
426
|
"function_call_available": True,
|
422
427
|
"response_format_available": True,
|
428
|
+
"native_multimodal": True,
|
423
429
|
},
|
424
430
|
"claude-3-sonnet-20240229": {
|
425
431
|
"id": "claude-3-sonnet-20240229",
|
426
432
|
"context_length": 200000,
|
427
433
|
"max_output_tokens": 4096,
|
428
434
|
"function_call_available": True,
|
435
|
+
"native_multimodal": True,
|
429
436
|
"response_format_available": True,
|
430
437
|
},
|
431
438
|
"claude-3-haiku-20240307": {
|
@@ -434,6 +441,7 @@ ANTHROPIC_MODELS = {
|
|
434
441
|
"max_output_tokens": 4096,
|
435
442
|
"function_call_available": True,
|
436
443
|
"response_format_available": True,
|
444
|
+
"native_multimodal": True,
|
437
445
|
},
|
438
446
|
"claude-3-5-sonnet-20240620": {
|
439
447
|
"id": "claude-3-5-sonnet-20240620",
|
@@ -441,6 +449,7 @@ ANTHROPIC_MODELS = {
|
|
441
449
|
"max_output_tokens": 4096,
|
442
450
|
"function_call_available": True,
|
443
451
|
"response_format_available": True,
|
452
|
+
"native_multimodal": True,
|
444
453
|
},
|
445
454
|
}
|
446
455
|
|
@@ -485,11 +494,13 @@ GEMINI_MODELS = {
|
|
485
494
|
"context_length": 1048576,
|
486
495
|
"function_call_available": True,
|
487
496
|
"response_format_available": True,
|
497
|
+
"native_multimodal": True,
|
488
498
|
},
|
489
499
|
"gemini-1.5-flash": {
|
490
500
|
"id": "gemini-1.5-flash",
|
491
501
|
"context_length": 1048576,
|
492
502
|
"function_call_available": True,
|
493
503
|
"response_format_available": True,
|
504
|
+
"native_multimodal": True,
|
494
505
|
},
|
495
506
|
}
|
@@ -30,6 +30,7 @@ class ModelSetting(BaseModel):
|
|
30
30
|
endpoints: List[str] = Field(default_factory=list, description="Available endpoints for the model.")
|
31
31
|
function_call_available: bool = Field(False, description="Indicates if function call is available.")
|
32
32
|
response_format_available: bool = Field(False, description="Indicates if response format is available.")
|
33
|
+
native_multimodal: bool = Field(False, description="Indicates if the model is a native multimodal model.")
|
33
34
|
context_length: int = Field(32768, description="The context length for the model.")
|
34
35
|
max_output_tokens: Optional[int] = Field(None, description="Maximum number of output tokens allowed.")
|
35
36
|
|
File without changes
|
vectorvein-0.1.14/tests/cat.png
DELETED
Binary file
|