model-library 0.1.2__py3-none-any.whl → 0.1.3__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,51 +1,27 @@
1
- import io
2
- from typing import Any, Literal, Sequence, cast
1
+ from typing import Literal
3
2
 
4
- from together import AsyncTogether
5
- from together.types.chat_completions import (
6
- ChatCompletionMessage,
7
- ChatCompletionResponse,
8
- )
9
3
  from typing_extensions import override
10
4
 
11
5
  from model_library import model_library_settings
12
6
  from model_library.base import (
13
- LLM,
14
- FileInput,
15
- FileWithBase64,
16
- FileWithId,
17
- FileWithUrl,
18
- InputItem,
7
+ DelegateOnly,
19
8
  LLMConfig,
20
- QueryResult,
9
+ ProviderConfig,
21
10
  QueryResultCost,
22
11
  QueryResultMetadata,
23
- TextInput,
24
- ToolDefinition,
25
- )
26
- from model_library.exceptions import (
27
- BadInputError,
28
- MaxOutputTokensExceededError,
29
- ModelNoOutputError,
30
12
  )
31
- from model_library.file_utils import trim_images
32
- from model_library.model_utils import get_reasoning_in_tag
33
13
  from model_library.providers.openai import OpenAIModel
34
14
  from model_library.register_models import register_provider
35
15
  from model_library.utils import create_openai_client_with_defaults
36
16
 
37
17
 
38
- @register_provider("together")
39
- class TogetherModel(LLM):
40
- _client: AsyncTogether | None = None
18
+ class TogetherConfig(ProviderConfig):
19
+ serverless: bool = True
41
20
 
42
- @override
43
- def get_client(self) -> AsyncTogether:
44
- if not TogetherModel._client:
45
- TogetherModel._client = AsyncTogether(
46
- api_key=model_library_settings.TOGETHER_API_KEY,
47
- )
48
- return TogetherModel._client
21
+
22
+ @register_provider("together")
23
+ class TogetherModel(DelegateOnly):
24
+ provider_config = TogetherConfig()
49
25
 
50
26
  def __init__(
51
27
  self,
@@ -55,187 +31,18 @@ class TogetherModel(LLM):
55
31
  config: LLMConfig | None = None,
56
32
  ):
57
33
  super().__init__(model_name, provider, config=config)
58
-
59
34
  # https://docs.together.ai/docs/openai-api-compatibility
60
- self.delegate: OpenAIModel | None = (
61
- None
62
- if self.native
63
- else OpenAIModel(
64
- model_name=model_name,
65
- provider=provider,
66
- config=config,
67
- custom_client=create_openai_client_with_defaults(
68
- api_key=model_library_settings.TOGETHER_API_KEY,
69
- base_url="https://api.together.xyz/v1",
70
- ),
71
- use_completions=False,
72
- )
73
- )
74
-
75
- @override
76
- async def parse_input(
77
- self,
78
- input: Sequence[InputItem],
79
- **kwargs: Any,
80
- ) -> list[dict[str, Any] | Any]:
81
- new_input: list[dict[str, Any] | Any] = []
82
- content_user: list[dict[str, Any]] = []
83
-
84
- def flush_content_user():
85
- nonlocal content_user
86
-
87
- if content_user:
88
- new_input.append({"role": "user", "content": content_user})
89
- content_user = []
90
-
91
- for item in input:
92
- match item:
93
- case TextInput():
94
- content_user.append({"type": "text", "text": item.text})
95
- case FileWithBase64() | FileWithUrl() | FileWithId():
96
- match item.type:
97
- case "image":
98
- content_user.append(await self.parse_image(item))
99
- case "file":
100
- content_user.append(await self.parse_file(item))
101
- case ChatCompletionMessage():
102
- flush_content_user()
103
- new_input.append(item)
104
- case _:
105
- raise BadInputError("Unsupported input type")
106
-
107
- flush_content_user()
108
-
109
- return new_input
110
-
111
- @override
112
- async def parse_image(
113
- self,
114
- image: FileInput,
115
- ) -> dict[str, Any]:
116
- match image:
117
- case FileWithBase64():
118
- return {
119
- "type": "image_url",
120
- "image_url": {
121
- "url": f"data:image/{image.mime};base64,{image.base64}"
122
- },
123
- }
124
- case _:
125
- # docs show that we can pass in s3 location somehow
126
- raise BadInputError("Unsupported image type")
127
-
128
- @override
129
- async def parse_file(
130
- self,
131
- file: FileInput,
132
- ) -> Any:
133
- raise NotImplementedError()
134
-
135
- @override
136
- async def parse_tools(
137
- self,
138
- tools: list[ToolDefinition],
139
- ) -> Any:
140
- raise NotImplementedError()
141
-
142
- @override
143
- async def upload_file(
144
- self,
145
- name: str,
146
- mime: str,
147
- bytes: io.BytesIO,
148
- type: Literal["image", "file"] = "file",
149
- ) -> FileWithId:
150
- raise NotImplementedError()
151
-
152
- @override
153
- async def _query_impl(
154
- self,
155
- input: Sequence[InputItem],
156
- *,
157
- tools: list[ToolDefinition],
158
- **kwargs: object,
159
- ) -> QueryResult:
160
- if self.delegate:
161
- return await self.delegate_query(input, tools=tools, **kwargs)
162
-
163
- # llama supports max 5 images
164
- if "lama-4" in self.model_name:
165
- input = trim_images(input, max_images=5)
166
-
167
- messages: list[dict[str, Any]] = []
168
-
169
- if "nemotron-super" in self.model_name:
170
- # move system prompt to prompt
171
- if "system_prompt" in kwargs:
172
- first_text_item = next(
173
- (item for item in input if isinstance(item, TextInput)), None
174
- )
175
- if not first_text_item:
176
- raise Exception(
177
- "Given system prompt for nemotron-super model, but no text input found"
178
- )
179
- system_prompt = kwargs.pop("system_prompt")
180
- first_text_item.text = f"SYSTEM PROMPT: {system_prompt}\nUSER PROMPT: {first_text_item.text}"
181
-
182
- # set system prompt to detailed thinking
183
- mode = "on" if self.reasoning else "off"
184
- kwargs["system_prompt"] = f"detailed thinking {mode}"
185
- messages.append(
186
- {
187
- "role": "system",
188
- "content": f"detailed thinking {mode}",
189
- }
190
- )
191
-
192
- if "system_prompt" in kwargs:
193
- messages.append({"role": "system", "content": kwargs.pop("system_prompt")})
194
-
195
- messages.extend(await self.parse_input(input))
196
-
197
- body: dict[str, Any] = {
198
- "max_tokens": self.max_tokens,
199
- "model": self.model_name,
200
- "messages": messages,
201
- }
202
-
203
- if self.supports_temperature:
204
- if self.temperature is not None:
205
- body["temperature"] = self.temperature
206
- if self.top_p is not None:
207
- body["top_p"] = self.top_p
208
-
209
- body.update(kwargs)
210
-
211
- response = await self.get_client().chat.completions.create(**body, stream=False) # pyright: ignore[reportAny]
212
-
213
- response = cast(ChatCompletionResponse, response)
214
-
215
- if not response or not response.choices or not response.choices[0].message:
216
- raise ModelNoOutputError("Model returned no completions")
217
-
218
- text = str(response.choices[0].message.content)
219
- reasoning = None
220
-
221
- if response.choices[0].finish_reason == "length" and not text:
222
- raise MaxOutputTokensExceededError()
223
-
224
- if self.reasoning:
225
- text, reasoning = get_reasoning_in_tag(text)
226
-
227
- output = QueryResult(
228
- output_text=text,
229
- reasoning=reasoning,
230
- history=[*input, response.choices[0].message],
35
+ self.delegate = OpenAIModel(
36
+ model_name=self.model_name,
37
+ provider=self.provider,
38
+ config=config,
39
+ custom_client=create_openai_client_with_defaults(
40
+ api_key=model_library_settings.TOGETHER_API_KEY,
41
+ base_url="https://api.together.xyz/v1",
42
+ ),
43
+ use_completions=True,
231
44
  )
232
45
 
233
- if response.usage:
234
- output.metadata.in_tokens = response.usage.prompt_tokens
235
- output.metadata.out_tokens = response.usage.completion_tokens
236
- # no cache tokens it seems
237
- return output
238
-
239
46
  @override
240
47
  async def _calculate_cost(
241
48
  self,
@@ -143,8 +143,6 @@ This has no effect on runtime use of ProviderConfig, only used to load the yaml
143
143
  class BaseProviderProperties(BaseModel):
144
144
  """Static base class for dynamic ProviderProperties."""
145
145
 
146
- pass
147
-
148
146
 
149
147
  def all_subclasses(cls: type) -> list[type]:
150
148
  """Recursively find all subclasses of a class."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: model-library
3
- Version: 0.1.2
3
+ Version: 0.1.3
4
4
  Summary: Model Library for vals.ai
5
5
  Author-email: "Vals AI, Inc." <contact@vals.ai>
6
6
  License: MIT
@@ -17,12 +17,11 @@ Requires-Dist: tiktoken==0.11.0
17
17
  Requires-Dist: pillow
18
18
  Requires-Dist: openai<2.0,>=1.97.1
19
19
  Requires-Dist: anthropic<1.0,>=0.57.1
20
- Requires-Dist: together<2.0,>=1.5.25
21
20
  Requires-Dist: mistralai<2.0,>=1.9.10
22
21
  Requires-Dist: xai-sdk<2.0,>=1.0.0
23
22
  Requires-Dist: ai21<5.0,>=4.0.3
24
23
  Requires-Dist: boto3<2.0,>=1.38.27
25
- Requires-Dist: google-genai[aiohttp]<2.0,>=1.48.0
24
+ Requires-Dist: google-genai[aiohttp]>=1.51.0
26
25
  Requires-Dist: google-cloud-storage>=1.26.0
27
26
  Dynamic: license-file
28
27
 
@@ -1,43 +1,43 @@
1
1
  model_library/__init__.py,sha256=AKc_15aklOf-LbcS9z1Xer_moRWNpG6Dh3kqvSQ0nOI,714
2
- model_library/exceptions.py,sha256=T_CEX6STyGPMFFAz4kXZg7fv6YfvPi8UJjRSeogP1fk,8845
3
- model_library/file_utils.py,sha256=vLxYWI0-kwp67UONcFdZw2qDTV38P7IZLBaXFJDNtO4,3666
2
+ model_library/exceptions.py,sha256=BWM3Gk7Lh_H4ttKtkvr4zcj01_UXb8e1PbKn8bl5Fgg,8953
3
+ model_library/file_utils.py,sha256=FAZRRtDT8c4Rjfoj64Te3knEHggXAAfRRuS8WLCsSe8,3682
4
4
  model_library/logging.py,sha256=McyaPHUk7RkB38-LrfnudrrU1B62ta8wAbbIBwLRmj0,853
5
5
  model_library/model_utils.py,sha256=l8oCltGeimMGtnne_3Q1EguVtzCj61UMsLsma-1czwg,753
6
6
  model_library/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- model_library/register_models.py,sha256=kAttwWA4tpb8WPnJSoANpQ0sa1ERWWgGx1EQcuuCaHI,13863
7
+ model_library/register_models.py,sha256=iVmzLDraUfzwF_bPz6DI2zMIeSUG1UQO9IdmGZTTui4,13853
8
8
  model_library/registry_utils.py,sha256=Op1NnQGD0XZyP032pGJdWdHgdEoHwKOcoWNCihT69SE,6977
9
9
  model_library/settings.py,sha256=QyeUqzWBpexFi014L_mZkoXP49no3SAQNJRObATXrL8,873
10
10
  model_library/utils.py,sha256=jQqBbP9vafpuFxp7kb53XYvCAtW79FtFJelnGGPn-pQ,4011
11
11
  model_library/base/__init__.py,sha256=TtxCXGUtkEqWZNMMofLPuC4orN7Ja2hemtbtHitt_UA,266
12
- model_library/base/base.py,sha256=gatrvBdSt2z2wOncgi4FtlPqvlOqmVfkRTh2eZcqgKk,13937
12
+ model_library/base/base.py,sha256=AyUt3XeFX3l1mVPf57IfqOnINdF3p2ziv5R3wz44VkM,14064
13
13
  model_library/base/batch.py,sha256=-jd6L0ECc5pkj73zoX2ZYcv_9iQdqxEi1kEilwaXWSA,2895
14
14
  model_library/base/delegate_only.py,sha256=V2MzENtvBg0pySKncgE-mfCLBhhRZ0y4BntQwQsxbqU,2111
15
15
  model_library/base/input.py,sha256=Nhg8Ril1kFau1DnE8u102JC1l-vxNd-v9e3SjovR-Do,1876
16
- model_library/base/output.py,sha256=5DG077lU-CNXVVfJAELaR4gJh0_bw3V5MwbgZIQphiY,5504
17
- model_library/base/utils.py,sha256=6okObx8VJc7xKmPR-tBFLTWFbnZTNhTdCPbuoV-Mef8,1246
18
- model_library/config/ai21labs_models.yaml,sha256=su8YrHwLTVfIvRrk4AFaLi_Xg1BU_-g8AK1ExKZUXSk,2547
16
+ model_library/base/output.py,sha256=v4s8Q_gYG2zxhhHQnDsAWFNPZHDx_kyLAhK7kxRhPjA,6673
17
+ model_library/base/utils.py,sha256=KJZRVWr38Tik3yNJvTXnBy62ccilzzmSxHZFpQBJMPo,1330
18
+ model_library/config/ai21labs_models.yaml,sha256=ykOwxkeWrhO98-V3sC5-FwXs0WLEeD1GZrM-VdTpF9o,2577
19
19
  model_library/config/alibaba_models.yaml,sha256=2tIdj_7Qiw_-jZmutdtdJWyAXPl4WEFh1ij3ubymov0,2252
20
- model_library/config/all_models.json,sha256=8XKNQbk0Zgmmkfio1kRDYs3MhFmaRQsVS30c0EENB4Y,488427
20
+ model_library/config/all_models.json,sha256=0i0aND49z9aBG19JpZp5Kk3Kt2nuj_mHaBJ9ZexYkwQ,497215
21
21
  model_library/config/amazon_models.yaml,sha256=RGj7DH0IzXNs4JmAk6adC2jUEefVxBJNVQIB-n-fXbc,8988
22
- model_library/config/anthropic_models.yaml,sha256=VHfmm2mRjKa0Ieusk0N4tRT_oy5BjIoNy1BkZJpEcnU,10490
22
+ model_library/config/anthropic_models.yaml,sha256=HszgDVQpv9EwSKwXd7T-eYIdQ3Ue07uNm8QjeRirFY0,11074
23
23
  model_library/config/cohere_models.yaml,sha256=BQSqIsGUXvULeFLGDFJNBxen-6CC5hKNW2s4lSC8Np0,5186
24
24
  model_library/config/deepseek_models.yaml,sha256=42bfyNZtaiOYx188FMqkfuCBSLNM1EBTYzf7hwzsjHw,1318
25
25
  model_library/config/dummy_model.yaml,sha256=CTnSdFYC-KTsHt5TvS0echWwUlb_H3eATZL1tVIkXkM,915
26
26
  model_library/config/fireworks_models.yaml,sha256=VG_Fo8X6qSA3VALn1SKehjj3B1HP0XO1fCYDdaCUdnM,5905
27
- model_library/config/google_models.yaml,sha256=QE9QjBrVlRDvuQ5tZ041VktcMJVGF7aAcYEJoBsimJQ,15661
27
+ model_library/config/google_models.yaml,sha256=kymR44OrrTygVSqI2PH3ffbpVYRuoxsAVP9ERq2fS18,16855
28
28
  model_library/config/inception_models.yaml,sha256=g6PC0qjEC2SUPTo2Rad34Dl8dt8ZBv1svaaP2_PIrYg,660
29
29
  model_library/config/kimi_models.yaml,sha256=BySTLTc0m24oBC94VegosQgxpHglthe5dGRwF-fyduo,840
30
30
  model_library/config/mistral_models.yaml,sha256=MjKEYFYcGBsFd6iXekE_1oGa3CmEWAVPABJR94gV6SE,3839
31
- model_library/config/openai_models.yaml,sha256=6ZpqIoSGbR-K0JQzOq8kjnQT-I78ap7psRpj_D-iUas,25283
31
+ model_library/config/openai_models.yaml,sha256=iSrX7WAZoNJOmVxrtEStnvRc-Md9z0CFYAIcC7GC_w8,25130
32
32
  model_library/config/perplexity_models.yaml,sha256=avTBrwnG-5Y6kle9t9vBrwcImhSzw-dgoYQuaw7K7Rs,2962
33
- model_library/config/together_models.yaml,sha256=9FtYtEyPFiuInfamuncg5b7PjSh-tc6k1448QulEIg4,24422
34
- model_library/config/xai_models.yaml,sha256=iNVTlpBXHF__KkvAQHgoyDPWrDvyIcOFHZOF8crAMVM,7798
33
+ model_library/config/together_models.yaml,sha256=VA2cuo9hgrQW3yOz5sYfUcMoU_AgNifQ6k1MjiXO3jk,24454
34
+ model_library/config/xai_models.yaml,sha256=xqXhXT3vpYC1iMzdnotj75oJ98nOwY6oFQY4gobAOmg,9328
35
35
  model_library/config/zai_models.yaml,sha256=lyAUPp4qOxkAAKCcbX48IKLaYYPAkp-Jn1wyCjLqmeA,1396
36
36
  model_library/providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
37
  model_library/providers/ai21labs.py,sha256=7PnXKl-Fv8KlE95eBv2izbFg1u7utDRQPdWXYVl_-as,5832
38
38
  model_library/providers/alibaba.py,sha256=k6LZErV_l9oTFTdKTwyw1SXD509Rl3AqFbN8umCryEE,2941
39
39
  model_library/providers/amazon.py,sha256=Qd5zAEn71WVo6c8mpPW0gE7WHLarzKzh6r4b_R4FaYk,13137
40
- model_library/providers/anthropic.py,sha256=iEQ5qRctp3iR_i4FZMWjKOIIifN2aGgW10j7Q8H4LhQ,22237
40
+ model_library/providers/anthropic.py,sha256=6YI04jdDDtDjLS17jThVYlNvLbqd9THrKAtaVTYL6eg,22194
41
41
  model_library/providers/azure.py,sha256=brQNCED-zHvYjL5K5hdjFBNso6hJZg0HTHNnAgJPPG0,1408
42
42
  model_library/providers/cohere.py,sha256=lCBm1PP1l_UOa1pKFMIZM3C0wCv3QWB6UP0-jvjkFa4,1066
43
43
  model_library/providers/deepseek.py,sha256=7T4lxDiV5wmWUK7TAKwr332_T6uyXNCOiirZOCCETL0,1159
@@ -45,17 +45,17 @@ model_library/providers/fireworks.py,sha256=w-5mOF5oNzqx_0ijCoTm1lSn2ZHwhp6fURKh
45
45
  model_library/providers/inception.py,sha256=Nrky53iujIM9spAWoNRtoJg2inFiL0li6E75vT3b6V8,1107
46
46
  model_library/providers/kimi.py,sha256=zzvcKpZLsM1xPebpLeMxNKTt_FRiLN1rFWrIly7wfXA,1092
47
47
  model_library/providers/mistral.py,sha256=DHl0BYUZOrCvD4La5cyzcpQKHh4RbTbgMORWFbU_TuQ,9536
48
- model_library/providers/openai.py,sha256=2hEJIgv5HnfrNhs_E3xzDpjV64QATJxu6R0R8JMMAV0,33447
48
+ model_library/providers/openai.py,sha256=ztJgx17e5PbbLVKsRA5Op0rczMsY4YNcgvRGKHRGlUQ,33572
49
49
  model_library/providers/perplexity.py,sha256=eIzzkaZ4ZMlRKFVI9bnwyo91iJkh7aEmJ-0_4OKeAWc,1083
50
- model_library/providers/together.py,sha256=ElE9k2H6kkMiK23yxz5-Czg6sOKDy80uyKAI1_oPM_4,8178
50
+ model_library/providers/together.py,sha256=7Y4QLnX8c_fyXUud-W_C1gidmROQainTgODBwbvFyXQ,2033
51
51
  model_library/providers/vals.py,sha256=VLF1rsCR13a_kmtZfboDzJJ64Io_tBFe60vf-0BdYPc,9830
52
52
  model_library/providers/xai.py,sha256=oJiMICYLkybHpLv77PmMbi1Xj9IUZmKX3kANksjjFEQ,10828
53
53
  model_library/providers/zai.py,sha256=O_GM6KlJ0fM2wYoxO9xrCWfnpYH7IpoKEzjiD4jB8Kc,1050
54
54
  model_library/providers/google/__init__.py,sha256=ypuLVL_QJEQ7C3S47FhC9y4wyawYOdGikAViJmACI0U,115
55
55
  model_library/providers/google/batch.py,sha256=4TE90Uo1adi54dVtGcGyUAxw11YExJq-Y4KmkQ-cyHA,9978
56
- model_library/providers/google/google.py,sha256=WKuQr4C-ZVcK6ew50YEHgcPA91pEafFXSI7cNi6nRlQ,16436
57
- model_library-0.1.2.dist-info/licenses/LICENSE,sha256=x6mf4o7U_wHaaqcfxoU-0R6uYJLbqL_TNuoULP3asaA,1070
58
- model_library-0.1.2.dist-info/METADATA,sha256=dEDbkl76pIIbzBEZ6qtTXMUxr3sX_-AO9vC76y8OSho,7034
59
- model_library-0.1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
60
- model_library-0.1.2.dist-info/top_level.txt,sha256=HtQYxA_7RP8UT35I6VcUw20L6edI0Zf2t5Ys1uDGVjs,14
61
- model_library-0.1.2.dist-info/RECORD,,
56
+ model_library/providers/google/google.py,sha256=s9vky9r5SVNhBvMXcIr0_h0MlKLXwx_tQlZzs57xXYo,16507
57
+ model_library-0.1.3.dist-info/licenses/LICENSE,sha256=x6mf4o7U_wHaaqcfxoU-0R6uYJLbqL_TNuoULP3asaA,1070
58
+ model_library-0.1.3.dist-info/METADATA,sha256=qnQqa4o9vNXB74vfgytR3qYSNr16HBOT7_iSDeAx0zw,6992
59
+ model_library-0.1.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
60
+ model_library-0.1.3.dist-info/top_level.txt,sha256=HtQYxA_7RP8UT35I6VcUw20L6edI0Zf2t5Ys1uDGVjs,14
61
+ model_library-0.1.3.dist-info/RECORD,,