vectorvein 0.1.41__py3-none-any.whl → 0.1.43__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,25 @@ 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
+ base_url = (
120
+ settings.token_server.url
121
+ if settings.token_server.url is not None
122
+ else f"http://{settings.token_server.host}:{settings.token_server.port}"
123
+ )
124
+ _, response = (
125
+ Retry(httpx.post)
126
+ .args(url=f"{base_url}/count_tokens", json={"text": text, "model": model}, timeout=None)
127
+ .retry_times(5)
128
+ .sleep_time(1)
129
+ .run()
130
+ )
131
+ if response is None:
132
+ return 1000
133
+ result = response.json()
134
+ return result["total_tokens"]
135
+
120
136
  if not isinstance(text, str):
121
137
  text = str(text)
122
138
  if model == "gpt-3.5-turbo":
@@ -188,7 +204,7 @@ def get_token_counts(text: str | dict, model: str = "") -> int:
188
204
  if isinstance(endpoint_id, dict):
189
205
  endpoint_id = endpoint_id["endpoint_id"]
190
206
  endpoint = settings.get_endpoint(endpoint_id)
191
- url = f"{endpoint.api_base}/models/{model_setting.id}:countTokens"
207
+ base_url = f"{endpoint.api_base}/models/{model_setting.id}:countTokens"
192
208
  params = {"key": endpoint.api_key}
193
209
  request_body = {
194
210
  "contents": {
@@ -200,7 +216,7 @@ def get_token_counts(text: str | dict, model: str = "") -> int:
200
216
  }
201
217
  _, response = (
202
218
  Retry(httpx.post)
203
- .args(url, json=request_body, params=params, timeout=None)
219
+ .args(base_url, json=request_body, params=params, timeout=None)
204
220
  .retry_times(5)
205
221
  .sleep_time(10)
206
222
  .run()
@@ -212,8 +228,12 @@ def get_token_counts(text: str | dict, model: str = "") -> int:
212
228
  elif model.startswith("claude"):
213
229
  return Anthropic().count_tokens(text)
214
230
  elif model.startswith("deepseek"):
231
+ from deepseek_tokenizer import deepseek_tokenizer
232
+
215
233
  return len(deepseek_tokenizer.encode(text))
216
234
  elif model.startswith("qwen"):
235
+ from qwen_tokenizer import get_tokenizer
236
+
217
237
  qwen_tokenizer = get_tokenizer(model)
218
238
  return len(qwen_tokenizer.encode(text))
219
239
  elif model.startswith("stepfun"):
@@ -380,6 +400,8 @@ def cutoff_messages(
380
400
 
381
401
 
382
402
  def format_image_message(image: str, backend: BackendType = BackendType.OpenAI) -> dict:
403
+ from ..utilities.media_processing import ImageProcessor
404
+
383
405
  image_processor = ImageProcessor(image_source=image)
384
406
  if backend == BackendType.OpenAI:
385
407
  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
+ if settings.token_server is None:
35
+ raise ValueError("Token server is not enabled.")
36
+
37
+ _host = settings.token_server.host
38
+ _port = settings.token_server.port
39
+ else:
40
+ _host = host
41
+ _port = port
42
+
43
+ uvicorn.run(token_server, host=_host, port=_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
 
@@ -9,10 +9,17 @@ from ..types.enums import BackendType
9
9
  from ..types.llm_parameters import BackendSettings, EndpointSetting
10
10
 
11
11
 
12
+ class Server(BaseModel):
13
+ host: str
14
+ port: int
15
+ url: Optional[str]
16
+
17
+
12
18
  class Settings(BaseModel):
13
19
  endpoints: List[EndpointSetting] = Field(
14
20
  default_factory=list, description="Available endpoints for the LLM service."
15
21
  )
22
+ token_server: Optional[Server] = Field(default=None, description="Token server address. Format: host:port")
16
23
 
17
24
  anthropic: BackendSettings = Field(default_factory=BackendSettings, description="Anthropic models settings.")
18
25
  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.43
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.43.dist-info/METADATA,sha256=XsswO1wZoO8V45KAfoTxijw_3n7Odna2N9zw-DGeEJ4,644
2
+ vectorvein-0.1.43.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
3
+ vectorvein-0.1.43.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=mzmN5qGDiF3B4ApMY_Xq4sOWs8kiskcrI7bzyFBCsa4,25475
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=36F9PKSNOX8ZtYBXY_l-76GQTpUSmQ2Y8EMy1H7wtdQ,1353
26
+ vectorvein/settings/__init__.py,sha256=dyTCLhevXiKVJhOb1tjgZGMH38Indy4dkWVdDX543g0,3771
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.43.dist-info/RECORD,,