meshapi 0.1.0__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.
- meshapi/__init__.py +251 -0
- meshapi/_errors.py +94 -0
- meshapi/_http.py +444 -0
- meshapi/_types.py +573 -0
- meshapi/resources/__init__.py +1 -0
- meshapi/resources/batches.py +60 -0
- meshapi/resources/chat.py +63 -0
- meshapi/resources/compare.py +43 -0
- meshapi/resources/embeddings.py +24 -0
- meshapi/resources/files.py +44 -0
- meshapi/resources/models.py +48 -0
- meshapi/resources/responses.py +43 -0
- meshapi/resources/templates.py +60 -0
- meshapi-0.1.0.dist-info/METADATA +519 -0
- meshapi-0.1.0.dist-info/RECORD +16 -0
- meshapi-0.1.0.dist-info/WHEEL +4 -0
meshapi/_types.py
ADDED
|
@@ -0,0 +1,573 @@
|
|
|
1
|
+
"""Domain types for MeshAPI SDK — all Pydantic v2 models."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any, Dict, List, Literal, Optional, Union
|
|
6
|
+
|
|
7
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
8
|
+
|
|
9
|
+
# ---------------------------------------------------------------------------
|
|
10
|
+
# Shared
|
|
11
|
+
# ---------------------------------------------------------------------------
|
|
12
|
+
|
|
13
|
+
ChatRole = Literal["system", "user", "assistant", "tool"]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ImageDetail(BaseModel):
|
|
17
|
+
model_config = ConfigDict(extra="ignore")
|
|
18
|
+
url: str
|
|
19
|
+
detail: Optional[Literal["auto", "low", "high"]] = None
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ContentPartText(BaseModel):
|
|
23
|
+
model_config = ConfigDict(extra="ignore")
|
|
24
|
+
type: Literal["text"]
|
|
25
|
+
text: str
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class ContentPartImage(BaseModel):
|
|
29
|
+
model_config = ConfigDict(extra="ignore")
|
|
30
|
+
type: Literal["image_url"]
|
|
31
|
+
image_url: ImageDetail
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class InputAudio(BaseModel):
|
|
35
|
+
model_config = ConfigDict(extra="ignore")
|
|
36
|
+
data: str
|
|
37
|
+
format: Literal["wav", "mp3", "aiff", "aac", "ogg", "flac", "m4a", "pcm16", "pcm24"]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class ContentPartAudio(BaseModel):
|
|
41
|
+
model_config = ConfigDict(extra="ignore")
|
|
42
|
+
type: Literal["input_audio"]
|
|
43
|
+
input_audio: InputAudio
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
ContentPart = Union[ContentPartText, ContentPartImage, ContentPartAudio]
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class ToolCallFunction(BaseModel):
|
|
50
|
+
model_config = ConfigDict(extra="ignore")
|
|
51
|
+
name: str
|
|
52
|
+
arguments: str # JSON-encoded string
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class ToolCall(BaseModel):
|
|
56
|
+
model_config = ConfigDict(extra="ignore")
|
|
57
|
+
id: str
|
|
58
|
+
type: Literal["function"]
|
|
59
|
+
function: ToolCallFunction
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class ChatMessage(BaseModel):
|
|
63
|
+
model_config = ConfigDict(extra="ignore")
|
|
64
|
+
role: ChatRole
|
|
65
|
+
content: Optional[Union[str, List[ContentPart]]] = None
|
|
66
|
+
name: Optional[str] = None
|
|
67
|
+
tool_call_id: Optional[str] = None
|
|
68
|
+
tool_calls: Optional[List[ToolCall]] = None
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class ToolFunction(BaseModel):
|
|
72
|
+
model_config = ConfigDict(extra="ignore")
|
|
73
|
+
name: str
|
|
74
|
+
description: Optional[str] = None
|
|
75
|
+
parameters: Optional[Dict[str, Any]] = None
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class Tool(BaseModel):
|
|
79
|
+
model_config = ConfigDict(extra="ignore")
|
|
80
|
+
type: Literal["function"]
|
|
81
|
+
function: ToolFunction
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class ToolChoiceFunction(BaseModel):
|
|
85
|
+
model_config = ConfigDict(extra="ignore")
|
|
86
|
+
name: str
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class ToolChoiceObject(BaseModel):
|
|
90
|
+
model_config = ConfigDict(extra="ignore")
|
|
91
|
+
type: Literal["function"]
|
|
92
|
+
function: ToolChoiceFunction
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
ToolChoice = Union[Literal["auto", "none", "required"], ToolChoiceObject]
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class AudioOutputOptions(BaseModel):
|
|
99
|
+
model_config = ConfigDict(extra="ignore")
|
|
100
|
+
voice: str = "alloy"
|
|
101
|
+
format: Literal["wav", "mp3", "flac", "opus", "pcm16"] = "wav"
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class ImageOptions(BaseModel):
|
|
105
|
+
model_config = ConfigDict(extra="ignore")
|
|
106
|
+
n: int = Field(default=1, ge=1, le=10)
|
|
107
|
+
size: str = "1024x1024"
|
|
108
|
+
quality: str = "high"
|
|
109
|
+
response_format: Literal["url", "b64_json"] = "url"
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
# ---------------------------------------------------------------------------
|
|
113
|
+
# Chat Completions
|
|
114
|
+
# ---------------------------------------------------------------------------
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
class ChatCompletionParams(BaseModel):
|
|
118
|
+
"""Request body for POST /v1/chat/completions."""
|
|
119
|
+
|
|
120
|
+
model_config = ConfigDict(extra="ignore")
|
|
121
|
+
|
|
122
|
+
messages: List[ChatMessage]
|
|
123
|
+
model: Optional[str] = None
|
|
124
|
+
stream: Optional[bool] = None
|
|
125
|
+
|
|
126
|
+
# MeshAPI extensions
|
|
127
|
+
template: Optional[str] = None
|
|
128
|
+
variables: Optional[Dict[str, str]] = None
|
|
129
|
+
session_id: Optional[str] = None
|
|
130
|
+
|
|
131
|
+
# Inference params
|
|
132
|
+
temperature: Optional[float] = None
|
|
133
|
+
max_tokens: Optional[int] = None
|
|
134
|
+
top_p: Optional[float] = None
|
|
135
|
+
frequency_penalty: Optional[float] = None
|
|
136
|
+
presence_penalty: Optional[float] = None
|
|
137
|
+
stop: Optional[Union[str, List[str]]] = None
|
|
138
|
+
seed: Optional[int] = None
|
|
139
|
+
tools: Optional[List[Tool]] = None
|
|
140
|
+
tool_choice: Optional[ToolChoice] = None
|
|
141
|
+
|
|
142
|
+
# OpenRouter-specific
|
|
143
|
+
transforms: Optional[List[str]] = None
|
|
144
|
+
models: Optional[List[str]] = None
|
|
145
|
+
|
|
146
|
+
user: Optional[str] = None
|
|
147
|
+
modality: Optional[Literal["text", "image"]] = None
|
|
148
|
+
image: Optional[ImageOptions] = None
|
|
149
|
+
async_mode: Optional[bool] = None
|
|
150
|
+
modalities: Optional[List[Literal["text", "audio"]]] = None
|
|
151
|
+
audio: Optional[AudioOutputOptions] = None
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class UsageInfo(BaseModel):
|
|
155
|
+
model_config = ConfigDict(extra="ignore")
|
|
156
|
+
prompt_tokens: int
|
|
157
|
+
completion_tokens: int
|
|
158
|
+
total_tokens: int
|
|
159
|
+
prompt_tokens_details: Optional[Dict[str, Any]] = None
|
|
160
|
+
completion_tokens_details: Optional[Dict[str, Any]] = None
|
|
161
|
+
classifier_prompt_tokens: Optional[int] = None
|
|
162
|
+
classifier_completion_tokens: Optional[int] = None
|
|
163
|
+
classifier_tokens: Optional[int] = None
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
class ChatCompletionMessage(BaseModel):
|
|
167
|
+
model_config = ConfigDict(extra="ignore")
|
|
168
|
+
role: str
|
|
169
|
+
content: Optional[Union[str, List[ContentPart]]] = None
|
|
170
|
+
tool_calls: Optional[List[ToolCall]] = None
|
|
171
|
+
audio: Optional[Dict[str, Any]] = None
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
class ChatCompletionChoice(BaseModel):
|
|
175
|
+
model_config = ConfigDict(extra="ignore")
|
|
176
|
+
index: int
|
|
177
|
+
message: Optional[ChatCompletionMessage] = None
|
|
178
|
+
finish_reason: Optional[str] = None
|
|
179
|
+
logprobs: Optional[Any] = None
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
class ChatCompletionResponse(BaseModel):
|
|
183
|
+
model_config = ConfigDict(extra="ignore")
|
|
184
|
+
id: str
|
|
185
|
+
object: str
|
|
186
|
+
created: int
|
|
187
|
+
model: str
|
|
188
|
+
choices: List[ChatCompletionChoice]
|
|
189
|
+
usage: Optional[UsageInfo] = None
|
|
190
|
+
system_fingerprint: Optional[str] = None
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
class ChatCompletionChunkDelta(BaseModel):
|
|
194
|
+
model_config = ConfigDict(extra="ignore")
|
|
195
|
+
role: Optional[str] = None
|
|
196
|
+
content: Optional[str] = None
|
|
197
|
+
tool_calls: Optional[List[ToolCall]] = None
|
|
198
|
+
audio: Optional[Dict[str, Any]] = None
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
class ChatCompletionChunkChoice(BaseModel):
|
|
202
|
+
model_config = ConfigDict(extra="ignore")
|
|
203
|
+
index: int
|
|
204
|
+
delta: Optional[ChatCompletionChunkDelta] = None
|
|
205
|
+
finish_reason: Optional[str] = None
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
class ChatCompletionChunk(BaseModel):
|
|
209
|
+
model_config = ConfigDict(extra="ignore")
|
|
210
|
+
id: str
|
|
211
|
+
object: str
|
|
212
|
+
created: int
|
|
213
|
+
model: str
|
|
214
|
+
choices: List[ChatCompletionChunkChoice]
|
|
215
|
+
usage: Optional[UsageInfo] = None
|
|
216
|
+
cost: Optional[str] = None
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
# ---------------------------------------------------------------------------
|
|
220
|
+
# Models
|
|
221
|
+
# ---------------------------------------------------------------------------
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
class ModelPricing(BaseModel):
|
|
225
|
+
model_config = ConfigDict(extra="ignore")
|
|
226
|
+
prompt_usd_per_1k: Optional[str] = None
|
|
227
|
+
completion_usd_per_1k: Optional[str] = None
|
|
228
|
+
image_usd_per_image: Optional[str] = None
|
|
229
|
+
discount_pct: Optional[str] = None
|
|
230
|
+
prompt_usd_per_1k_discounted: Optional[str] = None
|
|
231
|
+
completion_usd_per_1k_discounted: Optional[str] = None
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
class ModelInfo(BaseModel):
|
|
235
|
+
model_config = ConfigDict(extra="ignore")
|
|
236
|
+
id: str
|
|
237
|
+
name: str
|
|
238
|
+
context_length: Optional[int] = None
|
|
239
|
+
is_free: bool
|
|
240
|
+
pricing: Optional[ModelPricing] = None
|
|
241
|
+
description: Optional[str] = None
|
|
242
|
+
supports_thinking: Optional[bool] = None
|
|
243
|
+
supports_completions_api: Optional[bool] = None
|
|
244
|
+
supports_responses_api: Optional[bool] = None
|
|
245
|
+
model_type: Optional[str] = None
|
|
246
|
+
input_modalities: Optional[List[str]] = None
|
|
247
|
+
output_modalities: Optional[List[str]] = None
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
class ListModelsParams(BaseModel):
|
|
251
|
+
model_config = ConfigDict(extra="ignore")
|
|
252
|
+
free: Optional[bool] = None
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
# ---------------------------------------------------------------------------
|
|
256
|
+
# Templates
|
|
257
|
+
# ---------------------------------------------------------------------------
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
class TemplateMessage(BaseModel):
|
|
261
|
+
model_config = ConfigDict(extra="ignore")
|
|
262
|
+
role: str
|
|
263
|
+
content: str
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
class CreateTemplateParams(BaseModel):
|
|
267
|
+
model_config = ConfigDict(extra="ignore")
|
|
268
|
+
name: str
|
|
269
|
+
description: Optional[str] = None
|
|
270
|
+
system: Optional[str] = None
|
|
271
|
+
messages: Optional[List[Dict[str, Any]]] = None
|
|
272
|
+
model: Optional[str] = None
|
|
273
|
+
params: Optional[Dict[str, Any]] = None
|
|
274
|
+
variables: Optional[List[str]] = None
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
class UpdateTemplateParams(BaseModel):
|
|
278
|
+
model_config = ConfigDict(extra="ignore")
|
|
279
|
+
name: Optional[str] = None
|
|
280
|
+
description: Optional[str] = None
|
|
281
|
+
system: Optional[str] = None
|
|
282
|
+
messages: Optional[List[Dict[str, Any]]] = None
|
|
283
|
+
model: Optional[str] = None
|
|
284
|
+
params: Optional[Dict[str, Any]] = None
|
|
285
|
+
variables: Optional[List[str]] = None
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
class TemplateSummary(BaseModel):
|
|
289
|
+
model_config = ConfigDict(extra="ignore")
|
|
290
|
+
id: str
|
|
291
|
+
name: str
|
|
292
|
+
owner: Optional[str] = None
|
|
293
|
+
is_global: bool
|
|
294
|
+
description: Optional[str] = None
|
|
295
|
+
system: Optional[str] = None
|
|
296
|
+
messages: Optional[List[Dict[str, Any]]] = None
|
|
297
|
+
model: Optional[str] = None
|
|
298
|
+
params: Optional[Dict[str, Any]] = None
|
|
299
|
+
variables: Optional[List[str]] = None
|
|
300
|
+
created_at: str
|
|
301
|
+
updated_at: str
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
# ---------------------------------------------------------------------------
|
|
305
|
+
# Embeddings
|
|
306
|
+
# ---------------------------------------------------------------------------
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
class ProviderPreferences(BaseModel):
|
|
310
|
+
model_config = ConfigDict(extra="ignore")
|
|
311
|
+
order: Optional[List[str]] = None
|
|
312
|
+
allow_fallbacks: Optional[bool] = None
|
|
313
|
+
require_parameters: Optional[bool] = None
|
|
314
|
+
data_collection: Optional[Literal["allow", "deny"]] = None
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
class EmbeddingsParams(BaseModel):
|
|
318
|
+
model_config = ConfigDict(extra="ignore")
|
|
319
|
+
model: Optional[str] = None
|
|
320
|
+
input: Union[str, List[str], List[int], List[List[int]]]
|
|
321
|
+
dimensions: Optional[int] = Field(default=None, ge=1)
|
|
322
|
+
encoding_format: Optional[Literal["float", "base64"]] = None
|
|
323
|
+
input_type: Optional[str] = None
|
|
324
|
+
provider: Optional[Union[str, ProviderPreferences]] = None
|
|
325
|
+
user: Optional[str] = Field(default=None, max_length=256)
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
class EmbeddingItem(BaseModel):
|
|
329
|
+
model_config = ConfigDict(extra="ignore")
|
|
330
|
+
object: str
|
|
331
|
+
index: int
|
|
332
|
+
embedding: Union[List[float], str]
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
class EmbeddingsUsage(BaseModel):
|
|
336
|
+
model_config = ConfigDict(extra="ignore")
|
|
337
|
+
prompt_tokens: int
|
|
338
|
+
total_tokens: int
|
|
339
|
+
|
|
340
|
+
|
|
341
|
+
class EmbeddingsResponse(BaseModel):
|
|
342
|
+
model_config = ConfigDict(extra="ignore")
|
|
343
|
+
object: str
|
|
344
|
+
data: List[EmbeddingItem]
|
|
345
|
+
model: str
|
|
346
|
+
usage: Optional[EmbeddingsUsage] = None
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
# ---------------------------------------------------------------------------
|
|
350
|
+
# Responses
|
|
351
|
+
# ---------------------------------------------------------------------------
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
class BuiltinTool(BaseModel):
|
|
355
|
+
model_config = ConfigDict(extra="allow")
|
|
356
|
+
type: Literal[
|
|
357
|
+
"image_generation",
|
|
358
|
+
"web_search_preview",
|
|
359
|
+
"web_search_preview_2025_03_11",
|
|
360
|
+
"file_search",
|
|
361
|
+
"computer_use_preview",
|
|
362
|
+
"code_interpreter",
|
|
363
|
+
]
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
class ResponsesFunctionTool(BaseModel):
|
|
367
|
+
model_config = ConfigDict(extra="ignore")
|
|
368
|
+
type: Literal["function"] = "function"
|
|
369
|
+
name: str
|
|
370
|
+
description: Optional[str] = None
|
|
371
|
+
parameters: Optional[Dict[str, Any]] = None
|
|
372
|
+
strict: Optional[bool] = None
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
class ResponsesParams(BaseModel):
|
|
376
|
+
model_config = ConfigDict(extra="ignore")
|
|
377
|
+
model: Optional[str] = None
|
|
378
|
+
input: Union[str, List[Any]]
|
|
379
|
+
template: Optional[str] = None
|
|
380
|
+
variables: Optional[Dict[str, str]] = None
|
|
381
|
+
session_id: Optional[str] = None
|
|
382
|
+
stream: bool = False
|
|
383
|
+
max_output_tokens: Optional[int] = Field(default=None, ge=1)
|
|
384
|
+
temperature: Optional[float] = Field(default=None, ge=0.0, le=2.0)
|
|
385
|
+
top_p: Optional[float] = Field(default=None, ge=0.0, le=1.0)
|
|
386
|
+
seed: Optional[int] = None
|
|
387
|
+
reasoning: Optional[Dict[str, Any]] = None
|
|
388
|
+
tools: Optional[List[Union[ResponsesFunctionTool, BuiltinTool]]] = None
|
|
389
|
+
tool_choice: Optional[Union[str, Dict[str, Any]]] = None
|
|
390
|
+
response_format: Optional[Dict[str, Any]] = None
|
|
391
|
+
plugins: Optional[List[Any]] = None
|
|
392
|
+
user: Optional[str] = Field(default=None, max_length=256)
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
class ResponsesUsage(BaseModel):
|
|
396
|
+
model_config = ConfigDict(extra="ignore")
|
|
397
|
+
input_tokens: Optional[int] = None
|
|
398
|
+
output_tokens: Optional[int] = None
|
|
399
|
+
total_tokens: Optional[int] = None
|
|
400
|
+
prompt_tokens: Optional[int] = None
|
|
401
|
+
completion_tokens: Optional[int] = None
|
|
402
|
+
prompt_tokens_details: Optional[Dict[str, Any]] = None
|
|
403
|
+
completion_tokens_details: Optional[Dict[str, Any]] = None
|
|
404
|
+
classifier_tokens: Optional[int] = None
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
class ResponsesResponse(BaseModel):
|
|
408
|
+
model_config = ConfigDict(extra="allow")
|
|
409
|
+
id: Optional[str] = None
|
|
410
|
+
object: Optional[str] = None
|
|
411
|
+
model: Optional[str] = None
|
|
412
|
+
output: Optional[List[Any]] = None
|
|
413
|
+
usage: Optional[ResponsesUsage] = None
|
|
414
|
+
status: Optional[str] = None
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
class ResponsesStreamEvent(BaseModel):
|
|
418
|
+
model_config = ConfigDict(extra="allow")
|
|
419
|
+
type: Optional[str] = None
|
|
420
|
+
response: Optional[Dict[str, Any]] = None
|
|
421
|
+
usage: Optional[ResponsesUsage] = None
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
# ---------------------------------------------------------------------------
|
|
425
|
+
# Compare
|
|
426
|
+
# ---------------------------------------------------------------------------
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
class ModelOverride(BaseModel):
|
|
430
|
+
model_config = ConfigDict(extra="ignore")
|
|
431
|
+
model: str
|
|
432
|
+
temperature: Optional[float] = Field(default=None, ge=0.0, le=2.0)
|
|
433
|
+
max_tokens: Optional[int] = Field(default=None, ge=1)
|
|
434
|
+
system_prompt: Optional[str] = None
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
class CompareParams(BaseModel):
|
|
438
|
+
model_config = ConfigDict(extra="ignore")
|
|
439
|
+
models: List[str]
|
|
440
|
+
messages: List[ChatMessage]
|
|
441
|
+
model_overrides: Optional[List[ModelOverride]] = None
|
|
442
|
+
comparison_model: Optional[str] = None
|
|
443
|
+
comparison_instructions: Optional[str] = None
|
|
444
|
+
temperature: Optional[float] = Field(default=None, ge=0.0, le=2.0)
|
|
445
|
+
max_tokens: Optional[int] = Field(default=None, ge=1)
|
|
446
|
+
stream: bool = False
|
|
447
|
+
template: Optional[str] = None
|
|
448
|
+
variables: Optional[Dict[str, str]] = None
|
|
449
|
+
skip_comparison: bool = False
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
class TokenUsage(BaseModel):
|
|
453
|
+
model_config = ConfigDict(extra="ignore")
|
|
454
|
+
prompt_tokens: Optional[int] = None
|
|
455
|
+
completion_tokens: Optional[int] = None
|
|
456
|
+
total_tokens: Optional[int] = None
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
class ModelCompareResult(BaseModel):
|
|
460
|
+
model_config = ConfigDict(extra="ignore")
|
|
461
|
+
model: str
|
|
462
|
+
response_body: Optional[Dict[str, Any]] = None
|
|
463
|
+
content: Optional[str] = None
|
|
464
|
+
latency_ms: int
|
|
465
|
+
error: Optional[str] = None
|
|
466
|
+
error_code: Optional[str] = None
|
|
467
|
+
usage: Optional[TokenUsage] = None
|
|
468
|
+
request_id: str
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
class CompareResponse(BaseModel):
|
|
472
|
+
model_config = ConfigDict(extra="ignore")
|
|
473
|
+
comparison_id: str
|
|
474
|
+
object: str
|
|
475
|
+
created: int
|
|
476
|
+
models: List[str]
|
|
477
|
+
results: List[ModelCompareResult]
|
|
478
|
+
comparison: Optional[str] = None
|
|
479
|
+
comparison_model: Optional[str] = None
|
|
480
|
+
comparison_usage: Optional[TokenUsage] = None
|
|
481
|
+
comparison_fallback_used: bool = False
|
|
482
|
+
total_latency_ms: int
|
|
483
|
+
partial: bool = False
|
|
484
|
+
skip_comparison: bool = False
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
class CompareStreamEvent(BaseModel):
|
|
488
|
+
model_config = ConfigDict(extra="allow")
|
|
489
|
+
event: Optional[str] = None
|
|
490
|
+
data: Optional[Dict[str, Any]] = None
|
|
491
|
+
|
|
492
|
+
|
|
493
|
+
# ---------------------------------------------------------------------------
|
|
494
|
+
# Files / Batches
|
|
495
|
+
# ---------------------------------------------------------------------------
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
class BatchRequestItem(BaseModel):
|
|
499
|
+
model_config = ConfigDict(extra="ignore")
|
|
500
|
+
custom_id: str
|
|
501
|
+
method: str = "POST"
|
|
502
|
+
url: str = "/v1/chat/completions"
|
|
503
|
+
body: Dict[str, Any]
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
class UploadBatchFileParams(BaseModel):
|
|
507
|
+
model_config = ConfigDict(extra="ignore")
|
|
508
|
+
purpose: str = "batch"
|
|
509
|
+
requests: List[BatchRequestItem]
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
class FileObject(BaseModel):
|
|
513
|
+
model_config = ConfigDict(extra="allow")
|
|
514
|
+
id: str
|
|
515
|
+
object: Optional[str] = None
|
|
516
|
+
bytes: Optional[int] = None
|
|
517
|
+
created_at: Optional[int] = None
|
|
518
|
+
filename: Optional[str] = None
|
|
519
|
+
purpose: Optional[str] = None
|
|
520
|
+
status: Optional[str] = None
|
|
521
|
+
status_details: Optional[Any] = None
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
class CreateBatchParams(BaseModel):
|
|
525
|
+
model_config = ConfigDict(extra="ignore")
|
|
526
|
+
input_file_id: str
|
|
527
|
+
endpoint: str
|
|
528
|
+
completion_window: str
|
|
529
|
+
metadata: Optional[Dict[str, Any]] = None
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
class BatchObject(BaseModel):
|
|
533
|
+
model_config = ConfigDict(extra="allow")
|
|
534
|
+
id: str
|
|
535
|
+
object: Optional[str] = None
|
|
536
|
+
endpoint: Optional[str] = None
|
|
537
|
+
input_file_id: Optional[str] = None
|
|
538
|
+
output_file_id: Optional[str] = None
|
|
539
|
+
status: Optional[str] = None
|
|
540
|
+
model: Optional[str] = None
|
|
541
|
+
provider: Optional[str] = None
|
|
542
|
+
created_at: Optional[int] = None
|
|
543
|
+
completed_at: Optional[int] = None
|
|
544
|
+
usage_synced: Optional[bool] = None
|
|
545
|
+
|
|
546
|
+
|
|
547
|
+
class BatchListResponse(BaseModel):
|
|
548
|
+
model_config = ConfigDict(extra="allow")
|
|
549
|
+
object: str
|
|
550
|
+
data: List[BatchObject]
|
|
551
|
+
has_more: bool
|
|
552
|
+
first_id: Optional[str] = None
|
|
553
|
+
last_id: Optional[str] = None
|
|
554
|
+
|
|
555
|
+
|
|
556
|
+
# ---------------------------------------------------------------------------
|
|
557
|
+
# Error wire format
|
|
558
|
+
# ---------------------------------------------------------------------------
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
class ApiErrorBody(BaseModel):
|
|
562
|
+
model_config = ConfigDict(extra="ignore")
|
|
563
|
+
code: str
|
|
564
|
+
message: str
|
|
565
|
+
details: Optional[List[Any]] = None
|
|
566
|
+
provider_error: Optional[Dict[str, Any]] = None
|
|
567
|
+
retry_after_seconds: Optional[int] = None
|
|
568
|
+
|
|
569
|
+
|
|
570
|
+
class ApiErrorEnvelope(BaseModel):
|
|
571
|
+
model_config = ConfigDict(extra="ignore")
|
|
572
|
+
error: ApiErrorBody
|
|
573
|
+
request_id: str
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# resources package
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""Batch resource — /v1/batches endpoints."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from .._http import AsyncHttpClient, SyncHttpClient
|
|
6
|
+
from .._types import BatchListResponse, BatchObject, CreateBatchParams
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class BatchesResource:
|
|
10
|
+
def __init__(self, http: SyncHttpClient) -> None:
|
|
11
|
+
self._http = http
|
|
12
|
+
|
|
13
|
+
def create(self, params: CreateBatchParams) -> BatchObject:
|
|
14
|
+
data = self._http.post("/v1/batches", params.model_dump(exclude_none=True))
|
|
15
|
+
return BatchObject.model_validate(data)
|
|
16
|
+
|
|
17
|
+
def list(self, *, after: str | None = None, limit: int | None = None) -> BatchListResponse:
|
|
18
|
+
query = {}
|
|
19
|
+
if after is not None:
|
|
20
|
+
query["after"] = after
|
|
21
|
+
if limit is not None:
|
|
22
|
+
query["limit"] = str(limit)
|
|
23
|
+
data = self._http.get("/v1/batches", params=query or None)
|
|
24
|
+
return BatchListResponse.model_validate(data)
|
|
25
|
+
|
|
26
|
+
def get(self, batch_id: str) -> BatchObject:
|
|
27
|
+
data = self._http.get(f"/v1/batches/{batch_id}")
|
|
28
|
+
return BatchObject.model_validate(data)
|
|
29
|
+
|
|
30
|
+
def cancel(self, batch_id: str) -> BatchObject:
|
|
31
|
+
data = self._http.post(f"/v1/batches/{batch_id}/cancel", {})
|
|
32
|
+
return BatchObject.model_validate(data)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class AsyncBatchesResource:
|
|
36
|
+
def __init__(self, http: AsyncHttpClient) -> None:
|
|
37
|
+
self._http = http
|
|
38
|
+
|
|
39
|
+
async def create(self, params: CreateBatchParams) -> BatchObject:
|
|
40
|
+
data = await self._http.post("/v1/batches", params.model_dump(exclude_none=True))
|
|
41
|
+
return BatchObject.model_validate(data)
|
|
42
|
+
|
|
43
|
+
async def list(
|
|
44
|
+
self, *, after: str | None = None, limit: int | None = None
|
|
45
|
+
) -> BatchListResponse:
|
|
46
|
+
query = {}
|
|
47
|
+
if after is not None:
|
|
48
|
+
query["after"] = after
|
|
49
|
+
if limit is not None:
|
|
50
|
+
query["limit"] = str(limit)
|
|
51
|
+
data = await self._http.get("/v1/batches", params=query or None)
|
|
52
|
+
return BatchListResponse.model_validate(data)
|
|
53
|
+
|
|
54
|
+
async def get(self, batch_id: str) -> BatchObject:
|
|
55
|
+
data = await self._http.get(f"/v1/batches/{batch_id}")
|
|
56
|
+
return BatchObject.model_validate(data)
|
|
57
|
+
|
|
58
|
+
async def cancel(self, batch_id: str) -> BatchObject:
|
|
59
|
+
data = await self._http.post(f"/v1/batches/{batch_id}/cancel", {})
|
|
60
|
+
return BatchObject.model_validate(data)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"""Chat completions resource — POST /v1/chat/completions."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import AsyncIterator, Iterator
|
|
6
|
+
|
|
7
|
+
from .._http import AsyncHttpClient, SyncHttpClient
|
|
8
|
+
from .._types import ChatCompletionChunk, ChatCompletionParams, ChatCompletionResponse
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class CompletionsResource:
|
|
12
|
+
def __init__(self, http: SyncHttpClient) -> None:
|
|
13
|
+
self._http = http
|
|
14
|
+
|
|
15
|
+
def create(self, params: ChatCompletionParams) -> ChatCompletionResponse:
|
|
16
|
+
"""Non-streaming completion. Returns the full response."""
|
|
17
|
+
body = params.model_dump(exclude_none=True)
|
|
18
|
+
body["stream"] = False
|
|
19
|
+
data = self._http.post("/v1/chat/completions", body)
|
|
20
|
+
return ChatCompletionResponse.model_validate(data)
|
|
21
|
+
|
|
22
|
+
def stream(self, params: ChatCompletionParams) -> Iterator[ChatCompletionChunk]:
|
|
23
|
+
"""Streaming completion. Returns an iterator of SSE chunks.
|
|
24
|
+
|
|
25
|
+
Streams do NOT retry on failure. Catch MeshAPIApiError and
|
|
26
|
+
restart a new request if reconnection is needed.
|
|
27
|
+
"""
|
|
28
|
+
body = params.model_dump(exclude_none=True)
|
|
29
|
+
body["stream"] = True
|
|
30
|
+
yield from self._http.stream("/v1/chat/completions", body)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class ChatResource:
|
|
34
|
+
def __init__(self, http: SyncHttpClient) -> None:
|
|
35
|
+
self.completions = CompletionsResource(http)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class AsyncCompletionsResource:
|
|
39
|
+
def __init__(self, http: AsyncHttpClient) -> None:
|
|
40
|
+
self._http = http
|
|
41
|
+
|
|
42
|
+
async def create(self, params: ChatCompletionParams) -> ChatCompletionResponse:
|
|
43
|
+
"""Non-streaming completion."""
|
|
44
|
+
body = params.model_dump(exclude_none=True)
|
|
45
|
+
body["stream"] = False
|
|
46
|
+
data = await self._http.post("/v1/chat/completions", body)
|
|
47
|
+
return ChatCompletionResponse.model_validate(data)
|
|
48
|
+
|
|
49
|
+
async def stream(self, params: ChatCompletionParams) -> AsyncIterator[ChatCompletionChunk]:
|
|
50
|
+
"""Streaming completion. Returns an async iterator of SSE chunks.
|
|
51
|
+
|
|
52
|
+
Streams do NOT retry on failure. Catch MeshAPIApiError and
|
|
53
|
+
restart a new request if reconnection is needed.
|
|
54
|
+
"""
|
|
55
|
+
body = params.model_dump(exclude_none=True)
|
|
56
|
+
body["stream"] = True
|
|
57
|
+
async for chunk in self._http.stream("/v1/chat/completions", body):
|
|
58
|
+
yield chunk
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class AsyncChatResource:
|
|
62
|
+
def __init__(self, http: AsyncHttpClient) -> None:
|
|
63
|
+
self.completions = AsyncCompletionsResource(http)
|