vectorvein 0.1.75__py3-none-any.whl → 0.1.77__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.
@@ -1,7 +1,6 @@
1
1
  # @Author: Bi Ying
2
2
  # @Date: 2024-07-26 14:48:55
3
3
  import json
4
- import random
5
4
  from typing import overload, Generator, AsyncGenerator, Any, Literal, Iterable
6
5
 
7
6
  import httpx
@@ -29,7 +28,6 @@ from google.oauth2.credentials import Credentials
29
28
  from google.auth.transport.requests import Request
30
29
  from google.auth import _helpers
31
30
 
32
- from ..settings import settings
33
31
  from ..types import defaults as defs
34
32
  from .utils import cutoff_messages, get_message_token_counts
35
33
  from .base_client import BaseChatClient, BaseAsyncChatClient
@@ -40,7 +38,6 @@ from ..types.llm_parameters import (
40
38
  NotGiven,
41
39
  ToolParam,
42
40
  ToolChoice,
43
- EndpointSetting,
44
41
  AnthropicToolParam,
45
42
  AnthropicToolChoice,
46
43
  ChatCompletionMessage,
@@ -153,7 +150,7 @@ def refactor_into_openai_messages(messages: Iterable[MessageParam]):
153
150
 
154
151
 
155
152
  class AnthropicChatClient(BaseChatClient):
156
- DEFAULT_MODEL: str | None = defs.ANTHROPIC_DEFAULT_MODEL
153
+ DEFAULT_MODEL: str = defs.ANTHROPIC_DEFAULT_MODEL
157
154
  BACKEND_NAME: BackendType = BackendType.Anthropic
158
155
 
159
156
  def __init__(
@@ -180,44 +177,13 @@ class AnthropicChatClient(BaseChatClient):
180
177
  self.model_id = None
181
178
  self.endpoint = None
182
179
 
183
- def set_model_id_by_endpoint_id(self, endpoint_id: str):
184
- for endpoint_option in self.backend_settings.models[self.model].endpoints:
185
- if isinstance(endpoint_option, dict):
186
- if endpoint_id == endpoint_option["endpoint_id"]:
187
- self.model_id = endpoint_option["model_id"]
188
- break
189
- else:
190
- if endpoint_id == endpoint_option:
191
- self.model_id = endpoint_option
192
- break
193
- return self.model_id
194
-
195
- def _set_endpoint(self):
196
- if self.endpoint is None:
197
- if self.random_endpoint:
198
- self.random_endpoint = True
199
- endpoint = random.choice(self.backend_settings.models[self.model].endpoints)
200
- if isinstance(endpoint, dict):
201
- self.endpoint_id = endpoint["endpoint_id"]
202
- self.model_id = endpoint["model_id"]
203
- else:
204
- self.endpoint_id = endpoint
205
- self.endpoint = settings.get_endpoint(self.endpoint_id)
206
- else:
207
- self.endpoint = settings.get_endpoint(self.endpoint_id)
208
- self.set_model_id_by_endpoint_id(self.endpoint_id)
209
- elif isinstance(self.endpoint, EndpointSetting):
210
- self.endpoint_id = self.endpoint.id
211
- self.set_model_id_by_endpoint_id(self.endpoint_id)
212
- else:
213
- raise ValueError("Invalid endpoint")
214
-
215
- return self.endpoint, self.model_id
216
-
217
180
  @property
218
181
  def raw_client(self): # type: ignore
219
182
  self.endpoint, self.model_id = self._set_endpoint()
220
183
 
184
+ if self.endpoint.proxy is not None and self.http_client is None:
185
+ self.http_client = httpx.Client(proxy=self.endpoint.proxy)
186
+
221
187
  if self.endpoint.is_vertex:
222
188
  if self.endpoint.credentials is None:
223
189
  raise ValueError("Anthropic Vertex endpoint requires credentials")
@@ -565,7 +531,7 @@ class AnthropicChatClient(BaseChatClient):
565
531
 
566
532
 
567
533
  class AsyncAnthropicChatClient(BaseAsyncChatClient):
568
- DEFAULT_MODEL: str | None = defs.ANTHROPIC_DEFAULT_MODEL
534
+ DEFAULT_MODEL: str = defs.ANTHROPIC_DEFAULT_MODEL
569
535
  BACKEND_NAME: BackendType = BackendType.Anthropic
570
536
 
571
537
  def __init__(
@@ -592,44 +558,13 @@ class AsyncAnthropicChatClient(BaseAsyncChatClient):
592
558
  self.model_id = None
593
559
  self.endpoint = None
594
560
 
595
- def set_model_id_by_endpoint_id(self, endpoint_id: str):
596
- for endpoint_option in self.backend_settings.models[self.model].endpoints:
597
- if isinstance(endpoint_option, dict):
598
- if endpoint_id == endpoint_option["endpoint_id"]:
599
- self.model_id = endpoint_option["model_id"]
600
- break
601
- else:
602
- if endpoint_id == endpoint_option:
603
- self.model_id = endpoint_option
604
- break
605
- return self.model_id
606
-
607
- def _set_endpoint(self):
608
- if self.endpoint is None:
609
- if self.random_endpoint:
610
- self.random_endpoint = True
611
- endpoint = random.choice(self.backend_settings.models[self.model].endpoints)
612
- if isinstance(endpoint, dict):
613
- self.endpoint_id = endpoint["endpoint_id"]
614
- self.model_id = endpoint["model_id"]
615
- else:
616
- self.endpoint_id = endpoint
617
- self.endpoint = settings.get_endpoint(self.endpoint_id)
618
- else:
619
- self.endpoint = settings.get_endpoint(self.endpoint_id)
620
- self.set_model_id_by_endpoint_id(self.endpoint_id)
621
- elif isinstance(self.endpoint, EndpointSetting):
622
- self.endpoint_id = self.endpoint.id
623
- self.set_model_id_by_endpoint_id(self.endpoint_id)
624
- else:
625
- raise ValueError("Invalid endpoint")
626
-
627
- return self.endpoint, self.model_id
628
-
629
561
  @property
630
562
  def raw_client(self): # type: ignore
631
563
  self.endpoint, self.model_id = self._set_endpoint()
632
564
 
565
+ if self.endpoint.proxy is not None and self.http_client is None:
566
+ self.http_client = httpx.AsyncClient(proxy=self.endpoint.proxy)
567
+
633
568
  if self.endpoint.is_vertex:
634
569
  if self.endpoint.credentials is None:
635
570
  raise ValueError("Anthropic Vertex endpoint requires credentials")
@@ -1,5 +1,6 @@
1
1
  # @Author: Bi Ying
2
2
  # @Date: 2024-07-26 14:48:55
3
+ import random
3
4
  from abc import ABC, abstractmethod
4
5
  from functools import cached_property
5
6
  from typing import Generator, AsyncGenerator, Any, overload, Literal, Iterable
@@ -23,6 +24,7 @@ from ..types.llm_parameters import (
23
24
  NOT_GIVEN,
24
25
  ToolParam,
25
26
  ToolChoice,
27
+ EndpointSetting,
26
28
  ChatCompletionMessage,
27
29
  ChatCompletionDeltaMessage,
28
30
  ChatCompletionStreamOptionsParam,
@@ -30,7 +32,7 @@ from ..types.llm_parameters import (
30
32
 
31
33
 
32
34
  class BaseChatClient(ABC):
33
- DEFAULT_MODEL: str | None = None
35
+ DEFAULT_MODEL: str
34
36
  BACKEND_NAME: BackendType
35
37
 
36
38
  def __init__(
@@ -62,6 +64,35 @@ class BaseChatClient(ABC):
62
64
  self.random_endpoint = False
63
65
  self.endpoint = settings.get_endpoint(self.endpoint_id)
64
66
 
67
+ def set_model_id_by_endpoint_id(self, endpoint_id: str):
68
+ for endpoint_option in self.backend_settings.models[self.model].endpoints:
69
+ if isinstance(endpoint_option, dict) and endpoint_id == endpoint_option["endpoint_id"]:
70
+ self.model_id = endpoint_option["model_id"]
71
+ break
72
+ return self.model_id
73
+
74
+ def _set_endpoint(self):
75
+ if self.endpoint is None:
76
+ if self.random_endpoint:
77
+ self.random_endpoint = True
78
+ endpoint = random.choice(self.backend_settings.models[self.model].endpoints)
79
+ if isinstance(endpoint, dict):
80
+ self.endpoint_id = endpoint["endpoint_id"]
81
+ self.model_id = endpoint["model_id"]
82
+ else:
83
+ self.endpoint_id = endpoint
84
+ self.endpoint = settings.get_endpoint(self.endpoint_id)
85
+ else:
86
+ self.endpoint = settings.get_endpoint(self.endpoint_id)
87
+ self.set_model_id_by_endpoint_id(self.endpoint_id)
88
+ elif isinstance(self.endpoint, EndpointSetting):
89
+ self.endpoint_id = self.endpoint.id
90
+ self.set_model_id_by_endpoint_id(self.endpoint_id)
91
+ else:
92
+ raise ValueError("Invalid endpoint")
93
+
94
+ return self.endpoint, self.model_id
95
+
65
96
  @cached_property
66
97
  @abstractmethod
67
98
  def raw_client(
@@ -178,7 +209,7 @@ class BaseChatClient(ABC):
178
209
 
179
210
 
180
211
  class BaseAsyncChatClient(ABC):
181
- DEFAULT_MODEL: str | None = None
212
+ DEFAULT_MODEL: str
182
213
  BACKEND_NAME: BackendType
183
214
 
184
215
  def __init__(
@@ -210,6 +241,35 @@ class BaseAsyncChatClient(ABC):
210
241
  self.random_endpoint = False
211
242
  self.endpoint = settings.get_endpoint(self.endpoint_id)
212
243
 
244
+ def set_model_id_by_endpoint_id(self, endpoint_id: str):
245
+ for endpoint_option in self.backend_settings.models[self.model].endpoints:
246
+ if isinstance(endpoint_option, dict) and endpoint_id == endpoint_option["endpoint_id"]:
247
+ self.model_id = endpoint_option["model_id"]
248
+ break
249
+ return self.model_id
250
+
251
+ def _set_endpoint(self):
252
+ if self.endpoint is None:
253
+ if self.random_endpoint:
254
+ self.random_endpoint = True
255
+ endpoint = random.choice(self.backend_settings.models[self.model].endpoints)
256
+ if isinstance(endpoint, dict):
257
+ self.endpoint_id = endpoint["endpoint_id"]
258
+ self.model_id = endpoint["model_id"]
259
+ else:
260
+ self.endpoint_id = endpoint
261
+ self.endpoint = settings.get_endpoint(self.endpoint_id)
262
+ else:
263
+ self.endpoint = settings.get_endpoint(self.endpoint_id)
264
+ self.set_model_id_by_endpoint_id(self.endpoint_id)
265
+ elif isinstance(self.endpoint, EndpointSetting):
266
+ self.endpoint_id = self.endpoint.id
267
+ self.set_model_id_by_endpoint_id(self.endpoint_id)
268
+ else:
269
+ raise ValueError("Invalid endpoint")
270
+
271
+ return self.endpoint, self.model_id
272
+
213
273
  @cached_property
214
274
  @abstractmethod
215
275
  def raw_client(
@@ -1,13 +1,11 @@
1
1
  # @Author: Bi Ying
2
2
  # @Date: 2024-06-17 23:47:49
3
3
  import json
4
- import random
5
4
  from functools import cached_property
6
5
  from typing import Iterable, Literal, Generator, AsyncGenerator, overload, Any
7
6
 
8
7
  import httpx
9
8
 
10
- from ..settings import settings
11
9
  from .utils import cutoff_messages
12
10
  from ..types import defaults as defs
13
11
  from .base_client import BaseChatClient, BaseAsyncChatClient
@@ -24,7 +22,7 @@ from ..types.llm_parameters import (
24
22
 
25
23
 
26
24
  class GeminiChatClient(BaseChatClient):
27
- DEFAULT_MODEL: str | None = defs.GEMINI_DEFAULT_MODEL
25
+ DEFAULT_MODEL: str = defs.GEMINI_DEFAULT_MODEL
28
26
  BACKEND_NAME: BackendType = BackendType.Gemini
29
27
 
30
28
  def __init__(
@@ -48,9 +46,14 @@ class GeminiChatClient(BaseChatClient):
48
46
  http_client,
49
47
  backend_name,
50
48
  )
49
+ self.model_id = None
50
+ self.endpoint = None
51
51
 
52
52
  @cached_property
53
53
  def raw_client(self):
54
+ self.endpoint, self.model_id = self._set_endpoint()
55
+ if not self.http_client:
56
+ self.http_client = httpx.Client(timeout=300, proxy=self.endpoint.proxy)
54
57
  return self.http_client
55
58
 
56
59
  @overload
@@ -134,6 +137,10 @@ class GeminiChatClient(BaseChatClient):
134
137
  self.temperature = temperature
135
138
 
136
139
  self.model_setting = self.backend_settings.models[self.model]
140
+ if self.model_id is None:
141
+ self.model_id = self.model_setting.id
142
+
143
+ self.endpoint, self.model_id = self._set_endpoint()
137
144
 
138
145
  if messages[0].get("role") == "system":
139
146
  system_prompt = messages[0]["content"]
@@ -162,16 +169,6 @@ class GeminiChatClient(BaseChatClient):
162
169
  if top_p:
163
170
  top_p_params = {"top_p": top_p}
164
171
 
165
- if self.random_endpoint:
166
- self.random_endpoint = True
167
- endpoint_choice = random.choice(self.backend_settings.models[self.model].endpoints)
168
- if isinstance(endpoint_choice, dict):
169
- self.endpoint_id = endpoint_choice["endpoint_id"]
170
- self.model_id = endpoint_choice["model_id"]
171
- else:
172
- self.endpoint_id = endpoint_choice
173
- self.endpoint = settings.get_endpoint(self.endpoint_id)
174
-
175
172
  request_body = {
176
173
  "contents": messages,
177
174
  "safetySettings": [
@@ -202,10 +199,7 @@ class GeminiChatClient(BaseChatClient):
202
199
 
203
200
  def generator():
204
201
  result = {"content": "", "tool_calls": [], "usage": {}}
205
- if self.http_client:
206
- client = self.http_client
207
- else:
208
- client = httpx.Client(timeout=300)
202
+ client = self.raw_client
209
203
  with client.stream("POST", url, headers=headers, params=params, json=request_body) as response:
210
204
  for chunk in response.iter_lines():
211
205
  message = {"content": "", "tool_calls": []}
@@ -241,10 +235,7 @@ class GeminiChatClient(BaseChatClient):
241
235
  return generator()
242
236
  else:
243
237
  url = f"{self.endpoint.api_base}/models/{self.model_setting.id}:generateContent"
244
- if self.http_client:
245
- client = self.http_client
246
- else:
247
- client = httpx.Client(timeout=300)
238
+ client = self.raw_client
248
239
  response = client.post(url, json=request_body, headers=headers, params=params, timeout=None).json()
249
240
  if "error" in response:
250
241
  raise Exception(response["error"])
@@ -279,7 +270,7 @@ class GeminiChatClient(BaseChatClient):
279
270
 
280
271
 
281
272
  class AsyncGeminiChatClient(BaseAsyncChatClient):
282
- DEFAULT_MODEL: str | None = defs.GEMINI_DEFAULT_MODEL
273
+ DEFAULT_MODEL: str = defs.GEMINI_DEFAULT_MODEL
283
274
  BACKEND_NAME: BackendType = BackendType.Gemini
284
275
 
285
276
  def __init__(
@@ -303,9 +294,14 @@ class AsyncGeminiChatClient(BaseAsyncChatClient):
303
294
  http_client,
304
295
  backend_name,
305
296
  )
297
+ self.model_id = None
298
+ self.endpoint = None
306
299
 
307
300
  @cached_property
308
301
  def raw_client(self):
302
+ self.endpoint, self.model_id = self._set_endpoint()
303
+ if not self.http_client:
304
+ self.http_client = httpx.AsyncClient(timeout=300, proxy=self.endpoint.proxy)
309
305
  return self.http_client
310
306
 
311
307
  @overload
@@ -389,6 +385,10 @@ class AsyncGeminiChatClient(BaseAsyncChatClient):
389
385
  self.temperature = temperature
390
386
 
391
387
  self.model_setting = self.backend_settings.models[self.model]
388
+ if self.model_id is None:
389
+ self.model_id = self.model_setting.id
390
+
391
+ self.endpoint, self.model_id = self._set_endpoint()
392
392
 
393
393
  if messages[0].get("role") == "system":
394
394
  system_prompt = messages[0]["content"]
@@ -417,16 +417,6 @@ class AsyncGeminiChatClient(BaseAsyncChatClient):
417
417
  if top_p:
418
418
  top_p_params = {"top_p": top_p}
419
419
 
420
- if self.random_endpoint:
421
- self.random_endpoint = True
422
- endpoint_choice = random.choice(self.backend_settings.models[self.model].endpoints)
423
- if isinstance(endpoint_choice, dict):
424
- self.endpoint_id = endpoint_choice["endpoint_id"]
425
- self.model_id = endpoint_choice["model_id"]
426
- else:
427
- self.endpoint_id = endpoint_choice
428
- self.endpoint = settings.get_endpoint(self.endpoint_id)
429
-
430
420
  request_body = {
431
421
  "contents": messages,
432
422
  "safetySettings": [
@@ -457,10 +447,7 @@ class AsyncGeminiChatClient(BaseAsyncChatClient):
457
447
 
458
448
  async def generator():
459
449
  result = {"content": "", "tool_calls": [], "usage": {}}
460
- if self.http_client:
461
- client = self.http_client
462
- else:
463
- client = httpx.AsyncClient(timeout=300)
450
+ client = self.raw_client
464
451
  async with client.stream("POST", url, headers=headers, params=params, json=request_body) as response:
465
452
  async for chunk in response.aiter_lines():
466
453
  message = {"content": "", "tool_calls": []}
@@ -496,10 +483,7 @@ class AsyncGeminiChatClient(BaseAsyncChatClient):
496
483
  return generator()
497
484
  else:
498
485
  url = f"{self.endpoint.api_base}/models/{self.model_setting.id}:generateContent"
499
- if self.http_client:
500
- client = self.http_client
501
- else:
502
- client = httpx.AsyncClient(timeout=300)
486
+ client = self.raw_client
503
487
  async with client:
504
488
  response = await client.post(url, json=request_body, headers=headers, params=params, timeout=None)
505
489
  response = response.json()
@@ -1,12 +1,11 @@
1
1
  # @Author: Bi Ying
2
2
  # @Date: 2024-07-26 14:48:55
3
3
  import json
4
- import random
5
4
  from functools import cached_property
6
5
  from typing import Iterable, Literal, Generator, AsyncGenerator, overload, Any
6
+
7
7
  import httpx
8
8
 
9
- from ..settings import settings
10
9
  from ..types import defaults as defs
11
10
  from .utils import cutoff_messages, get_token_counts
12
11
  from .base_client import BaseChatClient, BaseAsyncChatClient
@@ -45,7 +44,7 @@ def extract_tool_calls(response):
45
44
 
46
45
 
47
46
  class MiniMaxChatClient(BaseChatClient):
48
- DEFAULT_MODEL: str | None = defs.MINIMAX_DEFAULT_MODEL
47
+ DEFAULT_MODEL: str = defs.MINIMAX_DEFAULT_MODEL
49
48
  BACKEND_NAME: BackendType = BackendType.MiniMax
50
49
 
51
50
  def __init__(
@@ -69,19 +68,20 @@ class MiniMaxChatClient(BaseChatClient):
69
68
  http_client,
70
69
  backend_name,
71
70
  )
72
- if http_client:
73
- self.http_client = http_client
74
- else:
75
- self.http_client = httpx.Client()
76
71
  self.model_id = None
72
+ self.endpoint = None
77
73
 
78
74
  @cached_property
79
75
  def raw_client(self):
76
+ self.endpoint, self.model_id = self._set_endpoint()
77
+ if not self.http_client:
78
+ self.http_client = httpx.Client(timeout=300, proxy=self.endpoint.proxy)
80
79
  return self.http_client
81
80
 
82
81
  @overload
83
82
  def create_completion(
84
83
  self,
84
+ *,
85
85
  messages: list,
86
86
  model: str | None = None,
87
87
  stream: Literal[False] = False,
@@ -100,9 +100,10 @@ class MiniMaxChatClient(BaseChatClient):
100
100
  @overload
101
101
  def create_completion(
102
102
  self,
103
+ *,
103
104
  messages: list,
104
105
  model: str | None = None,
105
- stream: Literal[True] = True,
106
+ stream: Literal[True],
106
107
  temperature: float | None = None,
107
108
  max_tokens: int | None = None,
108
109
  tools: Iterable[ToolParam] | NotGiven = NOT_GIVEN,
@@ -118,9 +119,10 @@ class MiniMaxChatClient(BaseChatClient):
118
119
  @overload
119
120
  def create_completion(
120
121
  self,
122
+ *,
121
123
  messages: list,
122
124
  model: str | None = None,
123
- stream: bool | None = None,
125
+ stream: bool,
124
126
  temperature: float | None = None,
125
127
  max_tokens: int | None = None,
126
128
  tools: Iterable[ToolParam] | NotGiven = NOT_GIVEN,
@@ -137,7 +139,7 @@ class MiniMaxChatClient(BaseChatClient):
137
139
  self,
138
140
  messages: list,
139
141
  model: str | None = None,
140
- stream: bool | None = None,
142
+ stream: Literal[False] | Literal[True] = False,
141
143
  temperature: float | None = None,
142
144
  max_tokens: int | None = None,
143
145
  tools: Iterable[ToolParam] | NotGiven = NOT_GIVEN,
@@ -160,15 +162,8 @@ class MiniMaxChatClient(BaseChatClient):
160
162
  self.model_setting = self.backend_settings.models[self.model]
161
163
  if self.model_id is None:
162
164
  self.model_id = self.model_setting.id
163
- if self.random_endpoint:
164
- self.random_endpoint = True
165
- endpoint_choice = random.choice(self.backend_settings.models[self.model].endpoints)
166
- if isinstance(endpoint_choice, dict):
167
- self.endpoint_id = endpoint_choice["endpoint_id"]
168
- self.model_id = endpoint_choice["model_id"]
169
- else:
170
- self.endpoint_id = endpoint_choice
171
- self.endpoint = settings.get_endpoint(self.endpoint_id)
165
+
166
+ self.endpoint, self.model_id = self._set_endpoint()
172
167
 
173
168
  if not skip_cutoff and self.context_length_control == ContextLengthControlType.Latest:
174
169
  messages = cutoff_messages(
@@ -221,7 +216,7 @@ class MiniMaxChatClient(BaseChatClient):
221
216
  )
222
217
  max_tokens = self.model_setting.context_length - token_counts
223
218
 
224
- self.url = self.endpoint.api_base
219
+ self.url = self.endpoint.api_base or "https://api.minimax.chat/v1/text/chatcompletion_v2"
225
220
  self.headers = {"Authorization": f"Bearer {self.endpoint.api_key}", "Content-Type": "application/json"}
226
221
 
227
222
  request_body = {
@@ -236,10 +231,12 @@ class MiniMaxChatClient(BaseChatClient):
236
231
  **kwargs,
237
232
  }
238
233
 
234
+ raw_client = self.raw_client
235
+
239
236
  if self.stream:
240
237
 
241
238
  def generator():
242
- with self.http_client.stream(
239
+ with raw_client.stream(
243
240
  "POST",
244
241
  url=self.url,
245
242
  headers=self.headers,
@@ -271,7 +268,7 @@ class MiniMaxChatClient(BaseChatClient):
271
268
 
272
269
  return generator()
273
270
  else:
274
- response = httpx.post(
271
+ response = raw_client.post(
275
272
  url=self.url,
276
273
  headers=self.headers,
277
274
  json=request_body,
@@ -294,7 +291,7 @@ class MiniMaxChatClient(BaseChatClient):
294
291
 
295
292
 
296
293
  class AsyncMiniMaxChatClient(BaseAsyncChatClient):
297
- DEFAULT_MODEL: str | None = defs.MINIMAX_DEFAULT_MODEL
294
+ DEFAULT_MODEL: str = defs.MINIMAX_DEFAULT_MODEL
298
295
  BACKEND_NAME: BackendType = BackendType.MiniMax
299
296
 
300
297
  def __init__(
@@ -318,19 +315,20 @@ class AsyncMiniMaxChatClient(BaseAsyncChatClient):
318
315
  http_client,
319
316
  backend_name,
320
317
  )
321
- if http_client:
322
- self.http_client = http_client
323
- else:
324
- self.http_client = httpx.AsyncClient()
325
318
  self.model_id = None
319
+ self.endpoint = None
326
320
 
327
321
  @cached_property
328
322
  def raw_client(self):
323
+ self.endpoint, self.model_id = self._set_endpoint()
324
+ if not self.http_client:
325
+ self.http_client = httpx.AsyncClient(timeout=300, proxy=self.endpoint.proxy)
329
326
  return self.http_client
330
327
 
331
328
  @overload
332
329
  async def create_completion(
333
330
  self,
331
+ *,
334
332
  messages: list,
335
333
  model: str | None = None,
336
334
  stream: Literal[False] = False,
@@ -349,9 +347,10 @@ class AsyncMiniMaxChatClient(BaseAsyncChatClient):
349
347
  @overload
350
348
  async def create_completion(
351
349
  self,
350
+ *,
352
351
  messages: list,
353
352
  model: str | None = None,
354
- stream: Literal[True] = True,
353
+ stream: Literal[True],
355
354
  temperature: float | None = None,
356
355
  max_tokens: int | None = None,
357
356
  tools: Iterable[ToolParam] | NotGiven = NOT_GIVEN,
@@ -367,9 +366,10 @@ class AsyncMiniMaxChatClient(BaseAsyncChatClient):
367
366
  @overload
368
367
  async def create_completion(
369
368
  self,
369
+ *,
370
370
  messages: list,
371
371
  model: str | None = None,
372
- stream: bool | None = None,
372
+ stream: bool,
373
373
  temperature: float | None = None,
374
374
  max_tokens: int | None = None,
375
375
  tools: Iterable[ToolParam] | NotGiven = NOT_GIVEN,
@@ -384,9 +384,10 @@ class AsyncMiniMaxChatClient(BaseAsyncChatClient):
384
384
 
385
385
  async def create_completion(
386
386
  self,
387
+ *,
387
388
  messages: list,
388
389
  model: str | None = None,
389
- stream: bool | None = None,
390
+ stream: Literal[False] | Literal[True] = False,
390
391
  temperature: float | None = None,
391
392
  max_tokens: int | None = None,
392
393
  tools: Iterable[ToolParam] | NotGiven = NOT_GIVEN,
@@ -409,15 +410,8 @@ class AsyncMiniMaxChatClient(BaseAsyncChatClient):
409
410
  self.model_setting = self.backend_settings.models[self.model]
410
411
  if self.model_id is None:
411
412
  self.model_id = self.model_setting.id
412
- if self.random_endpoint:
413
- self.random_endpoint = True
414
- endpoint_choice = random.choice(self.backend_settings.models[self.model].endpoints)
415
- if isinstance(endpoint_choice, dict):
416
- self.endpoint_id = endpoint_choice["endpoint_id"]
417
- self.model_id = endpoint_choice["model_id"]
418
- else:
419
- self.endpoint_id = endpoint_choice
420
- self.endpoint = settings.get_endpoint(self.endpoint_id)
413
+
414
+ self.endpoint, self.model_id = self._set_endpoint()
421
415
 
422
416
  if not skip_cutoff and self.context_length_control == ContextLengthControlType.Latest:
423
417
  messages = cutoff_messages(
@@ -468,7 +462,7 @@ class AsyncMiniMaxChatClient(BaseAsyncChatClient):
468
462
  )
469
463
  max_tokens = self.model_setting.context_length - token_counts
470
464
 
471
- self.url = self.endpoint.api_base
465
+ self.url = self.endpoint.api_base or "https://api.minimax.chat/v1/text/chatcompletion_v2"
472
466
  self.headers = {"Authorization": f"Bearer {self.endpoint.api_key}", "Content-Type": "application/json"}
473
467
 
474
468
  request_body = {
@@ -483,10 +477,12 @@ class AsyncMiniMaxChatClient(BaseAsyncChatClient):
483
477
  **kwargs,
484
478
  }
485
479
 
480
+ raw_client = self.raw_client
481
+
486
482
  if self.stream:
487
483
 
488
484
  async def generator():
489
- async with self.http_client.stream(
485
+ async with raw_client.stream(
490
486
  "POST",
491
487
  url=self.url,
492
488
  headers=self.headers,
@@ -519,7 +515,7 @@ class AsyncMiniMaxChatClient(BaseAsyncChatClient):
519
515
 
520
516
  return generator()
521
517
  else:
522
- response = await self.http_client.post(
518
+ response = await raw_client.post(
523
519
  url=self.url,
524
520
  headers=self.headers,
525
521
  json=request_body,
@@ -1,7 +1,6 @@
1
1
  # @Author: Bi Ying
2
2
  # @Date: 2024-07-26 14:48:55
3
3
  import json
4
- import random
5
4
  from functools import cached_property
6
5
  from typing import overload, Generator, AsyncGenerator, Any, Literal, Iterable
7
6
 
@@ -15,7 +14,6 @@ from .utils import (
15
14
  ToolCallContentProcessor,
16
15
  generate_tool_use_system_prompt,
17
16
  )
18
- from ..settings import settings
19
17
  from ..types import defaults as defs
20
18
  from ..types.enums import ContextLengthControlType, BackendType
21
19
  from ..types.llm_parameters import (
@@ -33,7 +31,7 @@ from ..types.llm_parameters import (
33
31
 
34
32
 
35
33
  class OpenAICompatibleChatClient(BaseChatClient):
36
- DEFAULT_MODEL: str | None = ""
34
+ DEFAULT_MODEL: str = ""
37
35
  BACKEND_NAME: BackendType
38
36
 
39
37
  def __init__(
@@ -58,19 +56,14 @@ class OpenAICompatibleChatClient(BaseChatClient):
58
56
  backend_name,
59
57
  )
60
58
  self.model_id = None
59
+ self.endpoint = None
61
60
 
62
61
  @cached_property
63
62
  def raw_client(self) -> OpenAI | AzureOpenAI:
64
- if self.random_endpoint:
65
- self.random_endpoint = True
66
- endpoint = random.choice(self.backend_settings.models[self.model].endpoints)
67
- self.model_id = None
68
- if isinstance(endpoint, dict):
69
- self.endpoint_id = endpoint["endpoint_id"]
70
- self.model_id = endpoint["model_id"]
71
- else:
72
- self.endpoint_id = endpoint
73
- self.endpoint = settings.get_endpoint(self.endpoint_id)
63
+ self.endpoint, self.model_id = self._set_endpoint()
64
+
65
+ if self.endpoint.proxy is not None and self.http_client is None:
66
+ self.http_client = httpx.Client(proxy=self.endpoint.proxy)
74
67
 
75
68
  if self.endpoint.is_azure:
76
69
  if self.endpoint.api_base is None:
@@ -78,7 +71,7 @@ class OpenAICompatibleChatClient(BaseChatClient):
78
71
  return AzureOpenAI(
79
72
  azure_endpoint=self.endpoint.api_base,
80
73
  api_key=self.endpoint.api_key,
81
- api_version="2024-10-01-preview",
74
+ api_version="2024-12-01-preview",
82
75
  http_client=self.http_client,
83
76
  )
84
77
  else:
@@ -305,7 +298,7 @@ class OpenAICompatibleChatClient(BaseChatClient):
305
298
 
306
299
 
307
300
  class AsyncOpenAICompatibleChatClient(BaseAsyncChatClient):
308
- DEFAULT_MODEL: str | None = ""
301
+ DEFAULT_MODEL: str = ""
309
302
  BACKEND_NAME: BackendType
310
303
 
311
304
  def __init__(
@@ -330,19 +323,14 @@ class AsyncOpenAICompatibleChatClient(BaseAsyncChatClient):
330
323
  backend_name,
331
324
  )
332
325
  self.model_id = None
326
+ self.endpoint = None
333
327
 
334
328
  @cached_property
335
329
  def raw_client(self):
336
- if self.random_endpoint:
337
- self.random_endpoint = True
338
- endpoint = random.choice(self.backend_settings.models[self.model].endpoints)
339
- self.model_id = None
340
- if isinstance(endpoint, dict):
341
- self.endpoint_id = endpoint["endpoint_id"]
342
- self.model_id = endpoint["model_id"]
343
- else:
344
- self.endpoint_id = endpoint
345
- self.endpoint = settings.get_endpoint(self.endpoint_id)
330
+ self.endpoint, self.model_id = self._set_endpoint()
331
+
332
+ if self.endpoint.proxy is not None and self.http_client is None:
333
+ self.http_client = httpx.AsyncClient(proxy=self.endpoint.proxy)
346
334
 
347
335
  if self.endpoint.is_azure:
348
336
  if self.endpoint.api_base is None:
@@ -350,7 +338,7 @@ class AsyncOpenAICompatibleChatClient(BaseAsyncChatClient):
350
338
  return AsyncAzureOpenAI(
351
339
  azure_endpoint=self.endpoint.api_base,
352
340
  api_key=self.endpoint.api_key,
353
- api_version="2024-10-01-preview",
341
+ api_version="2024-12-01-preview",
354
342
  http_client=self.http_client,
355
343
  )
356
344
  else:
@@ -419,6 +407,7 @@ class AsyncOpenAICompatibleChatClient(BaseAsyncChatClient):
419
407
 
420
408
  async def create_completion(
421
409
  self,
410
+ *,
422
411
  messages: list,
423
412
  model: str | None = None,
424
413
  stream: Literal[False] | Literal[True] = False,
@@ -44,6 +44,7 @@ class EndpointSetting(BaseModel):
44
44
  description="Whether to use concurrent requests for the LLM service.",
45
45
  default=defs.ENDPOINT_CONCURRENT_REQUESTS,
46
46
  )
47
+ proxy: Optional[str] = Field(None, description="The proxy URL for the endpoint.")
47
48
 
48
49
 
49
50
  class ModelSetting(BaseModel):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vectorvein
3
- Version: 0.1.75
3
+ Version: 0.1.77
4
4
  Summary: VectorVein python SDK
5
5
  Author-Email: Anderson <andersonby@163.com>
6
6
  License: MIT
@@ -1,20 +1,20 @@
1
- vectorvein-0.1.75.dist-info/METADATA,sha256=U3OoJo_4ayq0s27eH8tpJ10rQdeqQSKjU9ftsHfxnck,641
2
- vectorvein-0.1.75.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
3
- vectorvein-0.1.75.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
1
+ vectorvein-0.1.77.dist-info/METADATA,sha256=EGx61L2VDmmghx_inG3CK2RuFi3tp8H2VOprx_XuqSE,641
2
+ vectorvein-0.1.77.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
3
+ vectorvein-0.1.77.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=Oev7Lv1DIEWCMD-2Pm7e2cwzX7JFQTnIK-j6o4iUuyQ,17725
6
- vectorvein/chat_clients/anthropic_client.py,sha256=shRwgpbynExqX8l370_MTT7cGVhD4pE6VdPuf2AbI1E,40017
6
+ vectorvein/chat_clients/anthropic_client.py,sha256=Uy9E8t6hrYymNobRsPRCX5W-KsBXRun-8rAiRsN8M00,37217
7
7
  vectorvein/chat_clients/baichuan_client.py,sha256=CVMvpgjdrZGv0BWnTOBD-f2ufZ3wq3496wqukumsAr4,526
8
- vectorvein/chat_clients/base_client.py,sha256=Hl6xNnUnM_oS1uIg1sgyxb95aD6-yFxG51nTsFz8Whs,10671
8
+ vectorvein/chat_clients/base_client.py,sha256=Dar-2b7YR13YcWlH6sLIrKNr9_6IrpdUMjdwVFQyu0Q,13350
9
9
  vectorvein/chat_clients/deepseek_client.py,sha256=3qWu01NlJAP2N-Ff62d5-CZXZitlizE1fzb20LNetig,526
10
- vectorvein/chat_clients/gemini_client.py,sha256=ROVwflFyczkOxbJieqQHPTJk6XogZDKl1TFAvwZVyMU,21192
10
+ vectorvein/chat_clients/gemini_client.py,sha256=BsOhK4LI04pxak6wtmSju63it2P-zzIAXhCtgC6DfOQ,20453
11
11
  vectorvein/chat_clients/groq_client.py,sha256=Uow4pgdmFi93ZQSoOol2-0PhhqkW-S0XuSldvppz5U4,498
12
12
  vectorvein/chat_clients/local_client.py,sha256=55nOsxzqUf79q3Y14MKROA71zxhsT7p7FsDZ89rts2M,422
13
- vectorvein/chat_clients/minimax_client.py,sha256=2km4DYhBpOyiNlu9ykaXDuuhmuCMDFfb626PIJFp0eg,20126
13
+ vectorvein/chat_clients/minimax_client.py,sha256=TOfYDLJvs9JWSyU7S8V5SV3ozOC8anI2QEDdKy29HMk,19633
14
14
  vectorvein/chat_clients/mistral_client.py,sha256=1aKSylzBDaLYcFnaBIL4-sXSzWmXfBeON9Q0rq-ziWw,534
15
15
  vectorvein/chat_clients/moonshot_client.py,sha256=gbu-6nGxx8uM_U2WlI4Wus881rFRotzHtMSoYOcruGU,526
16
16
  vectorvein/chat_clients/openai_client.py,sha256=Nz6tV45pWcsOupxjnsRsGTicbQNJWIZyxuJoJ5DGMpg,527
17
- vectorvein/chat_clients/openai_compatible_client.py,sha256=h4D8dUscDcLshPcou-jWAZyGUP8cSTc-nTuXIBffZH8,23500
17
+ vectorvein/chat_clients/openai_compatible_client.py,sha256=tL_pj8OFhSo3yvHQxshjO695pTesaOrHLGVnkmfQZqw,22953
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
@@ -29,8 +29,8 @@ vectorvein/settings/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
29
29
  vectorvein/types/defaults.py,sha256=4qF31QJSFexF8E-Og8aGM0wCzegtPe65vxd8VQj7oKA,25579
30
30
  vectorvein/types/enums.py,sha256=7KTJSVtQueImmbr1fSwv3rQVtc0RyMWXJmoE2tDOaso,1667
31
31
  vectorvein/types/exception.py,sha256=gnW4GnJ76jND6UGnodk9xmqkcbeS7Cz2rvncA2HpD5E,69
32
- vectorvein/types/llm_parameters.py,sha256=g2Q0RKMC2vOcMI0tFpZ53xfVSfC8MLoK0YntPqce49U,5360
32
+ vectorvein/types/llm_parameters.py,sha256=I-b__6OZhobxneSOTWfoug2xJr6HBljanHVXU6cByUM,5447
33
33
  vectorvein/types/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
34
  vectorvein/utilities/media_processing.py,sha256=CTRq-lGlFkFgP_FSRhNwF_qUgmOrXPf2_1Ok9HY42_g,5887
35
35
  vectorvein/utilities/retry.py,sha256=6KFS9R2HdhqM3_9jkjD4F36ZSpEx2YNFGOVlpOsUetM,2208
36
- vectorvein-0.1.75.dist-info/RECORD,,
36
+ vectorvein-0.1.77.dist-info/RECORD,,