vectorvein 0.1.41__tar.gz → 0.1.42__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.
Files changed (34) hide show
  1. {vectorvein-0.1.41 → vectorvein-0.1.42}/PKG-INFO +4 -1
  2. {vectorvein-0.1.41 → vectorvein-0.1.42}/pyproject.toml +7 -1
  3. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/chat_clients/utils.py +21 -4
  4. vectorvein-0.1.42/src/vectorvein/server/token_server.py +47 -0
  5. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/settings/__init__.py +2 -1
  6. {vectorvein-0.1.41 → vectorvein-0.1.42}/README.md +0 -0
  7. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/__init__.py +0 -0
  8. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/chat_clients/__init__.py +0 -0
  9. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/chat_clients/anthropic_client.py +0 -0
  10. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/chat_clients/baichuan_client.py +0 -0
  11. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/chat_clients/base_client.py +0 -0
  12. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/chat_clients/deepseek_client.py +0 -0
  13. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/chat_clients/gemini_client.py +0 -0
  14. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/chat_clients/groq_client.py +0 -0
  15. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/chat_clients/local_client.py +0 -0
  16. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/chat_clients/minimax_client.py +0 -0
  17. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/chat_clients/mistral_client.py +0 -0
  18. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/chat_clients/moonshot_client.py +0 -0
  19. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/chat_clients/openai_client.py +0 -0
  20. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/chat_clients/openai_compatible_client.py +0 -0
  21. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/chat_clients/py.typed +0 -0
  22. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/chat_clients/qwen_client.py +0 -0
  23. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/chat_clients/stepfun_client.py +0 -0
  24. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/chat_clients/yi_client.py +0 -0
  25. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/chat_clients/zhipuai_client.py +0 -0
  26. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/py.typed +0 -0
  27. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/settings/py.typed +0 -0
  28. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/types/defaults.py +0 -0
  29. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/types/enums.py +0 -0
  30. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/types/exception.py +0 -0
  31. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/types/llm_parameters.py +0 -0
  32. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/types/py.typed +0 -0
  33. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/utilities/media_processing.py +0 -0
  34. {vectorvein-0.1.41 → vectorvein-0.1.42}/src/vectorvein/utilities/retry.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vectorvein
3
- Version: 0.1.41
3
+ Version: 0.1.42
4
4
  Summary: Default template for PDM package
5
5
  Author-Email: Anderson <andersonby@163.com>
6
6
  License: MIT
@@ -14,6 +14,9 @@ Requires-Dist: Pillow>=10.4.0
14
14
  Requires-Dist: deepseek-tokenizer>=0.1.0
15
15
  Requires-Dist: qwen-tokenizer>=0.2.0
16
16
  Requires-Dist: google-auth>=2.35.0
17
+ Provides-Extra: server
18
+ Requires-Dist: fastapi; extra == "server"
19
+ Requires-Dist: uvicorn; extra == "server"
17
20
  Description-Content-Type: text/markdown
18
21
 
19
22
  # vectorvein
@@ -17,11 +17,17 @@ description = "Default template for PDM package"
17
17
  name = "vectorvein"
18
18
  readme = "README.md"
19
19
  requires-python = ">=3.10"
20
- version = "0.1.41"
20
+ version = "0.1.42"
21
21
 
22
22
  [project.license]
23
23
  text = "MIT"
24
24
 
25
+ [project.optional-dependencies]
26
+ server = [
27
+ "fastapi",
28
+ "uvicorn",
29
+ ]
30
+
25
31
  [build-system]
26
32
  build-backend = "pdm.backend"
27
33
  requires = [
@@ -4,16 +4,14 @@ import re
4
4
  import json
5
5
  from math import ceil
6
6
  from typing import Iterable
7
+
7
8
  import httpx
8
9
  import tiktoken
9
10
  from anthropic import Anthropic
10
- from qwen_tokenizer import get_tokenizer
11
- from deepseek_tokenizer import deepseek_tokenizer
12
11
 
13
12
  from ..settings import settings
14
13
  from ..utilities.retry import Retry
15
14
  from ..types.enums import BackendType
16
- from ..utilities.media_processing import ImageProcessor
17
15
  from ..types.llm_parameters import (
18
16
  NotGiven,
19
17
  NOT_GIVEN,
@@ -116,7 +114,20 @@ def convert_type(value, value_type):
116
114
  return value # 如果类型未知,返回原始值
117
115
 
118
116
 
119
- def get_token_counts(text: str | dict, model: str = "") -> int:
117
+ def get_token_counts(text: str | dict, model: str = "", use_token_server_first: bool = False) -> int:
118
+ if use_token_server_first and settings.token_server is not None:
119
+ _, response = (
120
+ Retry(httpx.post)
121
+ .args(url=settings.token_server, json={"text": text, "model": model}, timeout=None)
122
+ .retry_times(5)
123
+ .sleep_time(1)
124
+ .run()
125
+ )
126
+ if response is None:
127
+ return 1000
128
+ result = response.json()
129
+ return result["total_tokens"]
130
+
120
131
  if not isinstance(text, str):
121
132
  text = str(text)
122
133
  if model == "gpt-3.5-turbo":
@@ -212,8 +223,12 @@ def get_token_counts(text: str | dict, model: str = "") -> int:
212
223
  elif model.startswith("claude"):
213
224
  return Anthropic().count_tokens(text)
214
225
  elif model.startswith("deepseek"):
226
+ from deepseek_tokenizer import deepseek_tokenizer
227
+
215
228
  return len(deepseek_tokenizer.encode(text))
216
229
  elif model.startswith("qwen"):
230
+ from qwen_tokenizer import get_tokenizer
231
+
217
232
  qwen_tokenizer = get_tokenizer(model)
218
233
  return len(qwen_tokenizer.encode(text))
219
234
  elif model.startswith("stepfun"):
@@ -380,6 +395,8 @@ def cutoff_messages(
380
395
 
381
396
 
382
397
  def format_image_message(image: str, backend: BackendType = BackendType.OpenAI) -> dict:
398
+ from ..utilities.media_processing import ImageProcessor
399
+
383
400
  image_processor = ImageProcessor(image_source=image)
384
401
  if backend == BackendType.OpenAI:
385
402
  return {
@@ -0,0 +1,47 @@
1
+ import uvicorn
2
+ from pydantic import BaseModel
3
+ from fastapi import FastAPI, HTTPException
4
+
5
+ from ..settings import settings
6
+ from ..chat_clients.utils import get_token_counts
7
+
8
+ token_server = FastAPI()
9
+
10
+
11
+ class TokenCountRequest(BaseModel):
12
+ text: str | dict
13
+ model: str = ""
14
+
15
+
16
+ @token_server.post("/count_tokens")
17
+ async def count_tokens(request: TokenCountRequest):
18
+ try:
19
+ token_count = get_token_counts(request.text, request.model, use_token_server_first=False)
20
+ return {"total_tokens": token_count}
21
+ except Exception as e:
22
+ raise HTTPException(status_code=500, detail=str(e))
23
+
24
+
25
+ def run_token_server(host: str | None = None, port: int | None = None):
26
+ """
27
+ 启动一个简单的HTTP服务器来处理token计数请求。参数均留空则使用 settings.token_server 的配置。
28
+
29
+ 参数:
30
+ host (str): 服务器主机地址。
31
+ port (int): 服务器端口。
32
+ """
33
+ if host is None or port is None:
34
+ token_server_url = settings.token_server
35
+ if token_server_url is None:
36
+ raise ValueError("Token server is not enabled.")
37
+
38
+ _host, _port = token_server_url.split(":")
39
+ else:
40
+ _host = host
41
+ _port = port
42
+
43
+ uvicorn.run(token_server, host=_host, port=int(_port))
44
+
45
+
46
+ if __name__ == "__main__":
47
+ run_token_server()
@@ -1,6 +1,6 @@
1
1
  # @Author: Bi Ying
2
2
  # @Date: 2024-07-27 00:30:56
3
- from typing import List, Dict
3
+ from typing import List, Dict, Optional
4
4
 
5
5
  from pydantic import BaseModel, Field
6
6
 
@@ -13,6 +13,7 @@ class Settings(BaseModel):
13
13
  endpoints: List[EndpointSetting] = Field(
14
14
  default_factory=list, description="Available endpoints for the LLM service."
15
15
  )
16
+ token_server: Optional[str] = Field(default=None, description="Token server address. Format: host:port")
16
17
 
17
18
  anthropic: BackendSettings = Field(default_factory=BackendSettings, description="Anthropic models settings.")
18
19
  deepseek: BackendSettings = Field(default_factory=BackendSettings, description="Deepseek models settings.")
File without changes