vectorvein 0.1.52__py3-none-any.whl → 0.1.54__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.
@@ -6,6 +6,7 @@ from typing import overload, Literal
6
6
  from .base_client import BaseChatClient, BaseAsyncChatClient
7
7
 
8
8
  from .yi_client import YiChatClient, AsyncYiChatClient
9
+ from .xai_client import XAIChatClient, AsyncXAIChatClient
9
10
  from .groq_client import GroqChatClient, AsyncGroqChatClient
10
11
  from .qwen_client import QwenChatClient, AsyncQwenChatClient
11
12
  from .local_client import LocalChatClient, AsyncLocalChatClient
@@ -41,6 +42,7 @@ BackendMap = {
41
42
  BackendType.ZhiPuAI: ZhiPuAIChatClient,
42
43
  BackendType.Baichuan: BaichuanChatClient,
43
44
  BackendType.StepFun: StepFunChatClient,
45
+ BackendType.XAI: XAIChatClient,
44
46
  },
45
47
  "async": {
46
48
  BackendType.Anthropic: AsyncAnthropicChatClient,
@@ -57,6 +59,7 @@ BackendMap = {
57
59
  BackendType.ZhiPuAI: AsyncZhiPuAIChatClient,
58
60
  BackendType.Baichuan: AsyncBaichuanChatClient,
59
61
  BackendType.StepFun: AsyncStepFunChatClient,
62
+ BackendType.XAI: AsyncXAIChatClient,
60
63
  },
61
64
  }
62
65
 
@@ -257,6 +260,20 @@ def create_chat_client(
257
260
  ) -> StepFunChatClient: ...
258
261
 
259
262
 
263
+ @overload
264
+ def create_chat_client(
265
+ backend: Literal[BackendType.XAI],
266
+ model: str | None = None,
267
+ stream: bool = False,
268
+ temperature: float = 0.7,
269
+ context_length_control: ContextLengthControlType = defs.CONTEXT_LENGTH_CONTROL,
270
+ random_endpoint: bool = True,
271
+ endpoint_id: str = "",
272
+ http_client: httpx.Client | None = None,
273
+ **kwargs,
274
+ ) -> XAIChatClient: ...
275
+
276
+
260
277
  @overload
261
278
  def create_chat_client(
262
279
  backend: BackendType,
@@ -496,6 +513,20 @@ def create_async_chat_client(
496
513
  ) -> AsyncStepFunChatClient: ...
497
514
 
498
515
 
516
+ @overload
517
+ def create_async_chat_client(
518
+ backend: Literal[BackendType.XAI],
519
+ model: str | None = None,
520
+ stream: bool = False,
521
+ temperature: float = 0.7,
522
+ context_length_control: ContextLengthControlType = defs.CONTEXT_LENGTH_CONTROL,
523
+ random_endpoint: bool = True,
524
+ endpoint_id: str = "",
525
+ http_client: httpx.AsyncClient | None = None,
526
+ **kwargs,
527
+ ) -> AsyncXAIChatClient: ...
528
+
529
+
499
530
  @overload
500
531
  def create_async_chat_client(
501
532
  backend: BackendType,
@@ -12,6 +12,7 @@ from anthropic import Anthropic, AnthropicVertex, AsyncAnthropic, AsyncAnthropic
12
12
  from anthropic._types import NOT_GIVEN
13
13
  from anthropic.types import (
14
14
  TextBlock,
15
+ MessageParam,
15
16
  ToolUseBlock,
16
17
  RawMessageDeltaEvent,
17
18
  RawMessageStartEvent,
@@ -112,6 +113,38 @@ def format_messages_alternate(messages: list) -> list:
112
113
  return formatted_messages
113
114
 
114
115
 
116
+ def refactor_into_openai_messages(messages: Iterable[MessageParam]):
117
+ formatted_messages = []
118
+ for message in messages:
119
+ content = message["content"]
120
+ if isinstance(content, str):
121
+ formatted_messages.append(message)
122
+ elif isinstance(content, list):
123
+ _content = []
124
+ for item in content:
125
+ if isinstance(item, (TextBlock, ToolUseBlock)):
126
+ _content.append(item.model_dump())
127
+ elif item.get("type") == "image":
128
+ image_data = item.get("source", {}).get("data", "")
129
+ media_type = item.get("source", {}).get("media_type", "")
130
+ data_url = f"data:{media_type};base64,{image_data}"
131
+ _content.append(
132
+ {
133
+ "type": "image_url",
134
+ "image_url": {
135
+ "url": data_url,
136
+ "detail_type": "auto",
137
+ },
138
+ }
139
+ )
140
+ else:
141
+ _content.append(item)
142
+ formatted_messages.append({"role": message["role"], "content": _content})
143
+ else:
144
+ formatted_messages.append(message)
145
+ return formatted_messages
146
+
147
+
115
148
  class AnthropicChatClient(BaseChatClient):
116
149
  DEFAULT_MODEL: str | None = defs.ANTHROPIC_DEFAULT_MODEL
117
150
  BACKEND_NAME: BackendType = BackendType.Anthropic
@@ -290,6 +323,9 @@ class AnthropicChatClient(BaseChatClient):
290
323
  if self.endpoint.api_schema_type == "openai":
291
324
  _tools = OPENAI_NOT_GIVEN if tools is NOT_GIVEN else tools
292
325
  _tool_choice = OPENAI_NOT_GIVEN if tool_choice is NOT_GIVEN else tool_choice
326
+
327
+ formatted_messages = refactor_into_openai_messages(messages)
328
+
293
329
  if self.stream:
294
330
 
295
331
  def _generator():
@@ -303,7 +339,16 @@ class AnthropicChatClient(BaseChatClient):
303
339
  http_client=self.http_client,
304
340
  backend_name=self.BACKEND_NAME,
305
341
  ).create_completion(
306
- messages, model, True, temperature, max_tokens, _tools, _tool_choice, response_format, **kwargs
342
+ messages=formatted_messages,
343
+ model=model,
344
+ stream=True,
345
+ temperature=temperature,
346
+ max_tokens=max_tokens,
347
+ tools=_tools,
348
+ tool_choice=_tool_choice,
349
+ response_format=response_format,
350
+ stream_options=stream_options,
351
+ **kwargs,
307
352
  )
308
353
  for chunk in response:
309
354
  yield chunk
@@ -320,7 +365,7 @@ class AnthropicChatClient(BaseChatClient):
320
365
  http_client=self.http_client,
321
366
  backend_name=self.BACKEND_NAME,
322
367
  ).create_completion(
323
- messages=messages,
368
+ messages=formatted_messages,
324
369
  model=model,
325
370
  stream=False,
326
371
  temperature=temperature,
@@ -643,6 +688,9 @@ class AsyncAnthropicChatClient(BaseAsyncChatClient):
643
688
  if self.endpoint.api_schema_type == "openai":
644
689
  _tools = OPENAI_NOT_GIVEN if tools is NOT_GIVEN else tools
645
690
  _tool_choice = OPENAI_NOT_GIVEN if tool_choice is NOT_GIVEN else tool_choice
691
+
692
+ formatted_messages = refactor_into_openai_messages(messages)
693
+
646
694
  if self.stream:
647
695
 
648
696
  async def _generator():
@@ -657,7 +705,7 @@ class AsyncAnthropicChatClient(BaseAsyncChatClient):
657
705
  backend_name=self.BACKEND_NAME,
658
706
  )
659
707
  response = await client.create_completion(
660
- messages=messages,
708
+ messages=formatted_messages,
661
709
  model=model,
662
710
  stream=True,
663
711
  temperature=temperature,
@@ -684,7 +732,15 @@ class AsyncAnthropicChatClient(BaseAsyncChatClient):
684
732
  backend_name=self.BACKEND_NAME,
685
733
  )
686
734
  return await client.create_completion(
687
- messages, model, False, temperature, max_tokens, _tools, _tool_choice, response_format, **kwargs
735
+ messages=formatted_messages,
736
+ model=model,
737
+ stream=False,
738
+ temperature=temperature,
739
+ max_tokens=max_tokens,
740
+ tools=_tools,
741
+ tool_choice=_tool_choice,
742
+ response_format=response_format,
743
+ **kwargs,
688
744
  )
689
745
 
690
746
  assert isinstance(self.raw_client, AsyncAnthropic | AsyncAnthropicVertex)
@@ -9,6 +9,7 @@ from typing import Iterable
9
9
  import httpx
10
10
  import tiktoken
11
11
  from anthropic import Anthropic
12
+ from openai.types.chat import ChatCompletionMessageParam
12
13
 
13
14
  from ..settings import settings
14
15
  from ..utilities.retry import Retry
@@ -567,7 +568,7 @@ def format_workflow_messages(message: dict, content: str, backend: BackendType):
567
568
  return formatted_messages
568
569
 
569
570
 
570
- def format_openai_message(message, backend):
571
+ def transform_from_openai_message(message: ChatCompletionMessageParam, backend: BackendType):
571
572
  role = message.get("role", "user")
572
573
  content = message.get("content", "")
573
574
 
@@ -635,7 +636,7 @@ def format_messages(
635
636
  formatted_messages.extend(format_workflow_messages(message, content, backend))
636
637
  else:
637
638
  # 处理 OpenAI 格式的消息
638
- formatted_message = format_openai_message(message, backend)
639
+ formatted_message = transform_from_openai_message(message, backend)
639
640
  formatted_messages.append(formatted_message)
640
641
 
641
642
  return formatted_messages
@@ -0,0 +1,15 @@
1
+ # @Author: Bi Ying
2
+ # @Date: 2024-07-26 14:48:55
3
+ from ..types.enums import BackendType
4
+ from ..types.defaults import XAI_DEFAULT_MODEL
5
+ from .openai_compatible_client import OpenAICompatibleChatClient, AsyncOpenAICompatibleChatClient
6
+
7
+
8
+ class XAIChatClient(OpenAICompatibleChatClient):
9
+ DEFAULT_MODEL = XAI_DEFAULT_MODEL
10
+ BACKEND_NAME = BackendType.XAI
11
+
12
+
13
+ class AsyncXAIChatClient(AsyncOpenAICompatibleChatClient):
14
+ DEFAULT_MODEL = XAI_DEFAULT_MODEL
15
+ BACKEND_NAME = BackendType.XAI
@@ -35,6 +35,7 @@ class Settings(BaseModel):
35
35
  zhipuai: BackendSettings = Field(default_factory=BackendSettings, description="Zhipuai models settings.")
36
36
  baichuan: BackendSettings = Field(default_factory=BackendSettings, description="Baichuan models settings.")
37
37
  stepfun: BackendSettings = Field(default_factory=BackendSettings, description="StepFun models settings.")
38
+ xai: BackendSettings = Field(default_factory=BackendSettings, description="XAI models settings.")
38
39
 
39
40
  def __init__(self, **data):
40
41
  model_types = {
@@ -724,3 +724,14 @@ STEPFUN_MODELS: Final[Dict[str, Dict[str, Any]]] = {
724
724
  "native_multimodal": True,
725
725
  },
726
726
  }
727
+
728
+
729
+ XAI_DEFAULT_MODEL: Final[str] = "grok-beta"
730
+ XAI_MODELS: Final[Dict[str, Dict[str, Any]]] = {
731
+ "grok-beta": {
732
+ "id": "grok-beta",
733
+ "context_length": 131072,
734
+ "function_call_available": True,
735
+ "response_format_available": True,
736
+ },
737
+ }
vectorvein/types/enums.py CHANGED
@@ -50,6 +50,9 @@ class BackendType(str, Enum):
50
50
  # StepFun
51
51
  StepFun = "stepfun"
52
52
 
53
+ # XAI
54
+ XAI = "xai"
55
+
53
56
  def __repr__(self):
54
57
  """Get a string representation."""
55
58
  return f'"{self.value}"'
@@ -36,7 +36,7 @@ class ImageProcessor:
36
36
  image_url = self.image_source
37
37
  response = httpx.get(image_url)
38
38
  return Image.open(BytesIO(response.content))
39
- elif isinstance(self.image_source, Path):
39
+ elif isinstance(self.image_source, (Path, str)):
40
40
  return Image.open(self.image_source)
41
41
  elif isinstance(self.image_source, Image.Image):
42
42
  return self.image_source
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vectorvein
3
- Version: 0.1.52
3
+ Version: 0.1.54
4
4
  Summary: Default template for PDM package
5
5
  Author-Email: Anderson <andersonby@163.com>
6
6
  License: MIT
@@ -1,9 +1,9 @@
1
- vectorvein-0.1.52.dist-info/METADATA,sha256=7Tl7WKTmbcQa7SG_fgPtxaZJbR8pOGzM5mOi07ivvpo,644
2
- vectorvein-0.1.52.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
3
- vectorvein-0.1.52.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
1
+ vectorvein-0.1.54.dist-info/METADATA,sha256=6BddXEmSVPZ4gez8n20Kr6XNLLUBaPANKrZZVtmS0kU,644
2
+ vectorvein-0.1.54.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
3
+ vectorvein-0.1.54.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
4
4
  vectorvein/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- vectorvein/chat_clients/__init__.py,sha256=dW169oK1n3v8Z0uD8itghzlCP72rxiaS-XYn6fvI2xM,16788
6
- vectorvein/chat_clients/anthropic_client.py,sha256=i1fMYSkUovd-Lc9B64bWMgzSTUFw4S3fj3AJ_pDokT4,34029
5
+ vectorvein/chat_clients/__init__.py,sha256=Oev7Lv1DIEWCMD-2Pm7e2cwzX7JFQTnIK-j6o4iUuyQ,17725
6
+ vectorvein/chat_clients/anthropic_client.py,sha256=G68JGM98E0pYyi8Tjvo4VQtnug9ncugFbb4d0DrPVQo,36122
7
7
  vectorvein/chat_clients/baichuan_client.py,sha256=CVMvpgjdrZGv0BWnTOBD-f2ufZ3wq3496wqukumsAr4,526
8
8
  vectorvein/chat_clients/base_client.py,sha256=0Uj0e-JR0a68sRS_WfUMVd91Av7lzJh6-DukjutlaD0,9497
9
9
  vectorvein/chat_clients/deepseek_client.py,sha256=3qWu01NlJAP2N-Ff62d5-CZXZitlizE1fzb20LNetig,526
@@ -18,18 +18,19 @@ vectorvein/chat_clients/openai_compatible_client.py,sha256=D2VmhpDVct4w2y58s87An
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=HUPtdn-OSxghJNCF5Q8PsL3Ye-1Nu16O84lntPqKyao,26439
21
+ vectorvein/chat_clients/utils.py,sha256=J-lv-XNlpFwcvLREqVZWKOA4QkN1t9XsOU6h0kxkWO4,26553
22
+ vectorvein/chat_clients/xai_client.py,sha256=eLFJJrNRJ-ni3DpshODcr3S1EJQLbhVwxyO1E54LaqM,491
22
23
  vectorvein/chat_clients/yi_client.py,sha256=RNf4CRuPJfixrwLZ3-DEc3t25QDe1mvZeb9sku2f8Bc,484
23
24
  vectorvein/chat_clients/zhipuai_client.py,sha256=Ys5DSeLCuedaDXr3PfG1EW2zKXopt-awO2IylWSwY0s,519
24
25
  vectorvein/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
26
  vectorvein/server/token_server.py,sha256=36F9PKSNOX8ZtYBXY_l-76GQTpUSmQ2Y8EMy1H7wtdQ,1353
26
- vectorvein/settings/__init__.py,sha256=dyTCLhevXiKVJhOb1tjgZGMH38Indy4dkWVdDX543g0,3771
27
+ vectorvein/settings/__init__.py,sha256=g01y74x0k2JEAqNpRGG0PDs0NTULjOAZV6HRhydPX1c,3874
27
28
  vectorvein/settings/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
- vectorvein/types/defaults.py,sha256=orYqYQiQj8lj1wzsQdnyHWC3bSVYhRB14Zkm6qQDYcU,22661
29
- vectorvein/types/enums.py,sha256=x_S0IJiEWijOAEiMNdiGDGEWGtmt7TwMriJVDqrDmTo,1637
29
+ vectorvein/types/defaults.py,sha256=BxnXL_Hz_gM8mYDI6Y62J660ipCanFlAturV9lDj3aQ,22940
30
+ vectorvein/types/enums.py,sha256=7KTJSVtQueImmbr1fSwv3rQVtc0RyMWXJmoE2tDOaso,1667
30
31
  vectorvein/types/exception.py,sha256=gnW4GnJ76jND6UGnodk9xmqkcbeS7Cz2rvncA2HpD5E,69
31
32
  vectorvein/types/llm_parameters.py,sha256=5o-C_yXxxQWZy_e8OWowB2107GTS-Eawx4Mvb1q55Co,5256
32
33
  vectorvein/types/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
- vectorvein/utilities/media_processing.py,sha256=cnzLrU1OaJvSv87IOnc36FrDXtmGMDStPbxtIJ33YN4,5880
34
+ vectorvein/utilities/media_processing.py,sha256=CTRq-lGlFkFgP_FSRhNwF_qUgmOrXPf2_1Ok9HY42_g,5887
34
35
  vectorvein/utilities/retry.py,sha256=6KFS9R2HdhqM3_9jkjD4F36ZSpEx2YNFGOVlpOsUetM,2208
35
- vectorvein-0.1.52.dist-info/RECORD,,
36
+ vectorvein-0.1.54.dist-info/RECORD,,