vectorvein 0.1.41__py3-none-any.whl → 0.1.42__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.
@@ -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.")
@@ -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
@@ -1,6 +1,6 @@
1
- vectorvein-0.1.41.dist-info/METADATA,sha256=ynJyDUbCKV8Uo4z_bRF18BemQWskfhV1WZoegG9QZJw,537
2
- vectorvein-0.1.41.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
3
- vectorvein-0.1.41.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
1
+ vectorvein-0.1.42.dist-info/METADATA,sha256=nsKbuRtzNcT0Qkrt1q9DSNoMzlAg0PoJBcQ6570T9mU,644
2
+ vectorvein-0.1.42.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
3
+ vectorvein-0.1.42.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
4
4
  vectorvein/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  vectorvein/chat_clients/__init__.py,sha256=dW169oK1n3v8Z0uD8itghzlCP72rxiaS-XYn6fvI2xM,16788
6
6
  vectorvein/chat_clients/anthropic_client.py,sha256=jF9pDlnkhjM6-OLPCQQxkh27xjzbTRaEY53olRd3_aY,32413
@@ -18,11 +18,12 @@ vectorvein/chat_clients/openai_compatible_client.py,sha256=FVm_ZYL9UP6t6hTUNxPyo
18
18
  vectorvein/chat_clients/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  vectorvein/chat_clients/qwen_client.py,sha256=-ryh-m9PgsO0fc4ulcCmPTy1155J8YUy15uPoJQOHA0,513
20
20
  vectorvein/chat_clients/stepfun_client.py,sha256=zsD2W5ahmR4DD9cqQTXmJr3txrGuvxbRWhFlRdwNijI,519
21
- vectorvein/chat_clients/utils.py,sha256=zEYT9EBLVtUeL-bxFnan3Ey9c6QMVvwI-koSzU4GmSU,24763
21
+ vectorvein/chat_clients/utils.py,sha256=CRwjzMkYRHs0onKf87KxseG08b4zjAjZxi00-gQPYHc,25253
22
22
  vectorvein/chat_clients/yi_client.py,sha256=RNf4CRuPJfixrwLZ3-DEc3t25QDe1mvZeb9sku2f8Bc,484
23
23
  vectorvein/chat_clients/zhipuai_client.py,sha256=Ys5DSeLCuedaDXr3PfG1EW2zKXopt-awO2IylWSwY0s,519
24
24
  vectorvein/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
- vectorvein/settings/__init__.py,sha256=0L-2WicBq9ctaJRoSwx8ZhVtX4slS5tHrIlSGf-tJxg,3564
25
+ vectorvein/server/token_server.py,sha256=mk7hbhagBc3q-5a7q3o0wNBkx-f0A4GTShqDD2bwkqA,1367
26
+ vectorvein/settings/__init__.py,sha256=tYC8hSAYIUxpcJTx7zhpTSdNqc5fVeYPE1IhOTTTpRA,3684
26
27
  vectorvein/settings/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
28
  vectorvein/types/defaults.py,sha256=xefmRNYBGbnWA5kjLLFKN91UM5gnHZ5-kcCNlQRfznk,22095
28
29
  vectorvein/types/enums.py,sha256=x_S0IJiEWijOAEiMNdiGDGEWGtmt7TwMriJVDqrDmTo,1637
@@ -31,4 +32,4 @@ vectorvein/types/llm_parameters.py,sha256=vhleSgCHzDl7EULYJ3dUYlu9KLbfs9y6dcPD0B
31
32
  vectorvein/types/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
33
  vectorvein/utilities/media_processing.py,sha256=cnzLrU1OaJvSv87IOnc36FrDXtmGMDStPbxtIJ33YN4,5880
33
34
  vectorvein/utilities/retry.py,sha256=6KFS9R2HdhqM3_9jkjD4F36ZSpEx2YNFGOVlpOsUetM,2208
34
- vectorvein-0.1.41.dist-info/RECORD,,
35
+ vectorvein-0.1.42.dist-info/RECORD,,