omniai-kit 1.0.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.
- omniai/__init__.py +117 -0
- omniai/_base.py +386 -0
- omniai/_constants.py +39 -0
- omniai/_version.py +4 -0
- omniai/client.py +316 -0
- omniai/exceptions.py +113 -0
- omniai/py.typed +1 -0
- omniai/resources/__init__.py +26 -0
- omniai/resources/chat.py +403 -0
- omniai/resources/livekit.py +71 -0
- omniai/resources/models.py +63 -0
- omniai/resources/router.py +1040 -0
- omniai/resources/tasks.py +171 -0
- omniai/types/__init__.py +27 -0
- omniai/types/chat.py +48 -0
- omniai/types/livekit.py +17 -0
- omniai/types/models.py +30 -0
- omniai/types/tasks.py +208 -0
- omniai_kit-1.0.0.dist-info/METADATA +270 -0
- omniai_kit-1.0.0.dist-info/RECORD +23 -0
- omniai_kit-1.0.0.dist-info/WHEEL +5 -0
- omniai_kit-1.0.0.dist-info/licenses/LICENSE +21 -0
- omniai_kit-1.0.0.dist-info/top_level.txt +1 -0
omniai/client.py
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
"""OmniAI Python Client SDK.
|
|
2
|
+
|
|
3
|
+
Provides synchronous and asynchronous clients with nested resource namespaces
|
|
4
|
+
and top-level convenience methods for chat, streaming, background tasks, and LiveKit sessions.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import logging
|
|
10
|
+
from typing import (
|
|
11
|
+
Any,
|
|
12
|
+
AsyncGenerator,
|
|
13
|
+
Dict,
|
|
14
|
+
Generator,
|
|
15
|
+
List,
|
|
16
|
+
Mapping,
|
|
17
|
+
Optional,
|
|
18
|
+
Type,
|
|
19
|
+
TypeVar,
|
|
20
|
+
Union,
|
|
21
|
+
)
|
|
22
|
+
import httpx
|
|
23
|
+
|
|
24
|
+
from omniai._base import AsyncBaseClient, BaseClient
|
|
25
|
+
from omniai._constants import (
|
|
26
|
+
DEFAULT_BASE_URL,
|
|
27
|
+
DEFAULT_MAX_RETRIES,
|
|
28
|
+
DEFAULT_TIMEOUT,
|
|
29
|
+
SUPPORTED_PROVIDERS,
|
|
30
|
+
)
|
|
31
|
+
from omniai.resources.chat import AsyncChatResource, ChatResource
|
|
32
|
+
from omniai.resources.livekit import AsyncLiveKitResource, LiveKitResource
|
|
33
|
+
from omniai.resources.models import AsyncModelsResource, ModelsResource
|
|
34
|
+
from omniai.resources.tasks import AsyncTasksResource, TasksResource
|
|
35
|
+
from omniai.types.livekit import LiveSessionInfo
|
|
36
|
+
from omniai.types.models import ModelInfo, ModelList
|
|
37
|
+
from omniai.types.tasks import AsyncTaskJob, TaskJob
|
|
38
|
+
|
|
39
|
+
logger = logging.getLogger("omniai.client")
|
|
40
|
+
|
|
41
|
+
T = TypeVar("T")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class OmniaiClient(BaseClient):
|
|
45
|
+
"""
|
|
46
|
+
Synchronous client for OmniAI.
|
|
47
|
+
|
|
48
|
+
Usage:
|
|
49
|
+
>>> from omniai import OmniaiClient
|
|
50
|
+
>>> client = OmniaiClient()
|
|
51
|
+
>>> response = client.chat(model="gemini:gemini-2.5-flash", prompt="Hello!")
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
def __init__(
|
|
55
|
+
self,
|
|
56
|
+
api_key: Optional[str] = None,
|
|
57
|
+
base_url: Optional[str] = None,
|
|
58
|
+
timeout: float = DEFAULT_TIMEOUT,
|
|
59
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
60
|
+
headers: Optional[Mapping[str, str]] = None,
|
|
61
|
+
http_client: Optional[httpx.Client] = None,
|
|
62
|
+
):
|
|
63
|
+
super().__init__(
|
|
64
|
+
api_key=api_key,
|
|
65
|
+
base_url=base_url,
|
|
66
|
+
timeout=timeout,
|
|
67
|
+
max_retries=max_retries,
|
|
68
|
+
headers=headers,
|
|
69
|
+
http_client=http_client,
|
|
70
|
+
)
|
|
71
|
+
self.chat = ChatResource(self)
|
|
72
|
+
self.models = ModelsResource(self)
|
|
73
|
+
self.tasks = TasksResource(self)
|
|
74
|
+
self.livekit = LiveKitResource(self)
|
|
75
|
+
|
|
76
|
+
def chat(
|
|
77
|
+
self,
|
|
78
|
+
model: str,
|
|
79
|
+
prompt: Optional[str] = None,
|
|
80
|
+
messages: Optional[List[Dict[str, str]]] = None,
|
|
81
|
+
response_model: Optional[Type[T]] = None,
|
|
82
|
+
tools: Optional[List[Any]] = None,
|
|
83
|
+
output_format: Optional[Union[str, Dict[str, Any]]] = None,
|
|
84
|
+
system_instruction: Optional[str] = None,
|
|
85
|
+
temperature: float = 0.1,
|
|
86
|
+
max_tokens: Optional[int] = None,
|
|
87
|
+
timeout: Optional[float] = None,
|
|
88
|
+
) -> Union[str, T]:
|
|
89
|
+
"""Convenience method to execute a chat completion."""
|
|
90
|
+
return self.chat.completions.create(
|
|
91
|
+
model=model,
|
|
92
|
+
prompt=prompt,
|
|
93
|
+
messages=messages,
|
|
94
|
+
response_model=response_model,
|
|
95
|
+
tools=tools,
|
|
96
|
+
output_format=output_format,
|
|
97
|
+
system_instruction=system_instruction,
|
|
98
|
+
temperature=temperature,
|
|
99
|
+
max_tokens=max_tokens,
|
|
100
|
+
timeout=timeout,
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
def stream(
|
|
104
|
+
self,
|
|
105
|
+
model: str,
|
|
106
|
+
prompt: Optional[str] = None,
|
|
107
|
+
messages: Optional[List[Dict[str, str]]] = None,
|
|
108
|
+
system_instruction: Optional[str] = None,
|
|
109
|
+
temperature: float = 0.1,
|
|
110
|
+
max_tokens: Optional[int] = None,
|
|
111
|
+
timeout: Optional[float] = None,
|
|
112
|
+
) -> Generator[str, None, None]:
|
|
113
|
+
"""Convenience method to stream a chat completion chunk-by-chunk."""
|
|
114
|
+
return self.chat.completions.stream(
|
|
115
|
+
model=model,
|
|
116
|
+
prompt=prompt,
|
|
117
|
+
messages=messages,
|
|
118
|
+
system_instruction=system_instruction,
|
|
119
|
+
temperature=temperature,
|
|
120
|
+
max_tokens=max_tokens,
|
|
121
|
+
timeout=timeout,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
def submit_task(
|
|
125
|
+
self,
|
|
126
|
+
model: str,
|
|
127
|
+
prompt: Optional[str] = None,
|
|
128
|
+
messages: Optional[List[Dict[str, str]]] = None,
|
|
129
|
+
response_model: Optional[Type[T]] = None,
|
|
130
|
+
tools: Optional[List[Any]] = None,
|
|
131
|
+
output_format: Optional[Union[str, Dict[str, Any]]] = None,
|
|
132
|
+
system_instruction: Optional[str] = None,
|
|
133
|
+
temperature: float = 0.1,
|
|
134
|
+
max_tokens: Optional[int] = None,
|
|
135
|
+
timeout: Optional[float] = None,
|
|
136
|
+
) -> TaskJob[T]:
|
|
137
|
+
"""Submits a background task to the OmniAI Celery queue."""
|
|
138
|
+
return self.tasks.submit(
|
|
139
|
+
model=model,
|
|
140
|
+
prompt=prompt,
|
|
141
|
+
messages=messages,
|
|
142
|
+
response_model=response_model,
|
|
143
|
+
tools=tools,
|
|
144
|
+
output_format=output_format,
|
|
145
|
+
system_instruction=system_instruction,
|
|
146
|
+
temperature=temperature,
|
|
147
|
+
max_tokens=max_tokens,
|
|
148
|
+
timeout=timeout,
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
def create_live_session(
|
|
152
|
+
self,
|
|
153
|
+
model: str = "gemini:gemini-2.5-flash",
|
|
154
|
+
voice: str = "Aoede",
|
|
155
|
+
video_input: bool = False,
|
|
156
|
+
timeout: Optional[float] = None,
|
|
157
|
+
) -> LiveSessionInfo:
|
|
158
|
+
"""Requests room and participant credentials for a LiveKit WebRTC session."""
|
|
159
|
+
return self.livekit.create_session(
|
|
160
|
+
model=model,
|
|
161
|
+
voice=voice,
|
|
162
|
+
video_input=video_input,
|
|
163
|
+
timeout=timeout,
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
def list_models(self, timeout: Optional[float] = None) -> ModelList:
|
|
167
|
+
"""Lists available AI models."""
|
|
168
|
+
return self.models.list(timeout=timeout)
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
class AsyncOmniaiClient(AsyncBaseClient):
|
|
172
|
+
"""
|
|
173
|
+
Asynchronous client for OmniAI.
|
|
174
|
+
|
|
175
|
+
Usage:
|
|
176
|
+
>>> import asyncio
|
|
177
|
+
>>> from omniai import AsyncOmniaiClient
|
|
178
|
+
>>> async def main():
|
|
179
|
+
... async with AsyncOmniaiClient() as client:
|
|
180
|
+
... res = await client.chat(model="gemini:gemini-2.5-flash", prompt="Hello!")
|
|
181
|
+
... print(res)
|
|
182
|
+
>>> asyncio.run(main())
|
|
183
|
+
"""
|
|
184
|
+
|
|
185
|
+
def __init__(
|
|
186
|
+
self,
|
|
187
|
+
api_key: Optional[str] = None,
|
|
188
|
+
base_url: Optional[str] = None,
|
|
189
|
+
timeout: float = DEFAULT_TIMEOUT,
|
|
190
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
191
|
+
headers: Optional[Mapping[str, str]] = None,
|
|
192
|
+
http_client: Optional[httpx.AsyncClient] = None,
|
|
193
|
+
):
|
|
194
|
+
super().__init__(
|
|
195
|
+
api_key=api_key,
|
|
196
|
+
base_url=base_url,
|
|
197
|
+
timeout=timeout,
|
|
198
|
+
max_retries=max_retries,
|
|
199
|
+
headers=headers,
|
|
200
|
+
http_client=http_client,
|
|
201
|
+
)
|
|
202
|
+
self.chat = AsyncChatResource(self)
|
|
203
|
+
self.models = AsyncModelsResource(self)
|
|
204
|
+
self.tasks = AsyncTasksResource(self)
|
|
205
|
+
self.livekit = AsyncLiveKitResource(self)
|
|
206
|
+
|
|
207
|
+
async def chat(
|
|
208
|
+
self,
|
|
209
|
+
model: str,
|
|
210
|
+
prompt: Optional[str] = None,
|
|
211
|
+
messages: Optional[List[Dict[str, str]]] = None,
|
|
212
|
+
response_model: Optional[Type[T]] = None,
|
|
213
|
+
tools: Optional[List[Any]] = None,
|
|
214
|
+
output_format: Optional[Union[str, Dict[str, Any]]] = None,
|
|
215
|
+
system_instruction: Optional[str] = None,
|
|
216
|
+
temperature: float = 0.1,
|
|
217
|
+
max_tokens: Optional[int] = None,
|
|
218
|
+
timeout: Optional[float] = None,
|
|
219
|
+
) -> Union[str, T]:
|
|
220
|
+
"""Convenience method to execute an async chat completion."""
|
|
221
|
+
return await self.chat.completions.create(
|
|
222
|
+
model=model,
|
|
223
|
+
prompt=prompt,
|
|
224
|
+
messages=messages,
|
|
225
|
+
response_model=response_model,
|
|
226
|
+
tools=tools,
|
|
227
|
+
output_format=output_format,
|
|
228
|
+
system_instruction=system_instruction,
|
|
229
|
+
temperature=temperature,
|
|
230
|
+
max_tokens=max_tokens,
|
|
231
|
+
timeout=timeout,
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
async def stream(
|
|
235
|
+
self,
|
|
236
|
+
model: str,
|
|
237
|
+
prompt: Optional[str] = None,
|
|
238
|
+
messages: Optional[List[Dict[str, str]]] = None,
|
|
239
|
+
system_instruction: Optional[str] = None,
|
|
240
|
+
temperature: float = 0.1,
|
|
241
|
+
max_tokens: Optional[int] = None,
|
|
242
|
+
timeout: Optional[float] = None,
|
|
243
|
+
) -> AsyncGenerator[str, None]:
|
|
244
|
+
"""Convenience method to stream an async chat completion chunk-by-chunk."""
|
|
245
|
+
async for chunk in self.chat.completions.stream(
|
|
246
|
+
model=model,
|
|
247
|
+
prompt=prompt,
|
|
248
|
+
messages=messages,
|
|
249
|
+
system_instruction=system_instruction,
|
|
250
|
+
temperature=temperature,
|
|
251
|
+
max_tokens=max_tokens,
|
|
252
|
+
timeout=timeout,
|
|
253
|
+
):
|
|
254
|
+
yield chunk
|
|
255
|
+
|
|
256
|
+
async def submit_task(
|
|
257
|
+
self,
|
|
258
|
+
model: str,
|
|
259
|
+
prompt: Optional[str] = None,
|
|
260
|
+
messages: Optional[List[Dict[str, str]]] = None,
|
|
261
|
+
response_model: Optional[Type[T]] = None,
|
|
262
|
+
tools: Optional[List[Any]] = None,
|
|
263
|
+
output_format: Optional[Union[str, Dict[str, Any]]] = None,
|
|
264
|
+
system_instruction: Optional[str] = None,
|
|
265
|
+
temperature: float = 0.1,
|
|
266
|
+
max_tokens: Optional[int] = None,
|
|
267
|
+
timeout: Optional[float] = None,
|
|
268
|
+
) -> AsyncTaskJob[T]:
|
|
269
|
+
"""Submits an async background task to the OmniAI Celery queue."""
|
|
270
|
+
return await self.tasks.submit(
|
|
271
|
+
model=model,
|
|
272
|
+
prompt=prompt,
|
|
273
|
+
messages=messages,
|
|
274
|
+
response_model=response_model,
|
|
275
|
+
tools=tools,
|
|
276
|
+
output_format=output_format,
|
|
277
|
+
system_instruction=system_instruction,
|
|
278
|
+
temperature=temperature,
|
|
279
|
+
max_tokens=max_tokens,
|
|
280
|
+
timeout=timeout,
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
async def create_live_session(
|
|
284
|
+
self,
|
|
285
|
+
model: str = "gemini:gemini-2.5-flash",
|
|
286
|
+
voice: str = "Aoede",
|
|
287
|
+
video_input: bool = False,
|
|
288
|
+
timeout: Optional[float] = None,
|
|
289
|
+
) -> LiveSessionInfo:
|
|
290
|
+
"""Requests room and participant credentials for a LiveKit WebRTC session asynchronously."""
|
|
291
|
+
return await self.livekit.create_session(
|
|
292
|
+
model=model,
|
|
293
|
+
voice=voice,
|
|
294
|
+
video_input=video_input,
|
|
295
|
+
timeout=timeout,
|
|
296
|
+
)
|
|
297
|
+
|
|
298
|
+
async def list_models(self, timeout: Optional[float] = None) -> ModelList:
|
|
299
|
+
"""Lists available AI models asynchronously."""
|
|
300
|
+
return await self.models.list(timeout=timeout)
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
# Aliases for brand and convenience consistency
|
|
304
|
+
OmniAIClient = OmniaiClient
|
|
305
|
+
AsyncOmniAIClient = AsyncOmniaiClient
|
|
306
|
+
OmniClient = OmniaiClient
|
|
307
|
+
AsyncOmniClient = AsyncOmniaiClient
|
|
308
|
+
|
|
309
|
+
__all__ = [
|
|
310
|
+
"OmniaiClient",
|
|
311
|
+
"AsyncOmniaiClient",
|
|
312
|
+
"OmniAIClient",
|
|
313
|
+
"AsyncOmniAIClient",
|
|
314
|
+
"OmniClient",
|
|
315
|
+
"AsyncOmniClient",
|
|
316
|
+
]
|
omniai/exceptions.py
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, Optional
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class OmniaiError(Exception):
|
|
7
|
+
"""Base exception for all errors raised by the OmniAI Python SDK."""
|
|
8
|
+
|
|
9
|
+
def __init__(self, message: str, details: Optional[Dict[str, Any]] = None):
|
|
10
|
+
super().__init__(message)
|
|
11
|
+
self.message = message
|
|
12
|
+
self.details = details or {}
|
|
13
|
+
|
|
14
|
+
def __str__(self) -> str:
|
|
15
|
+
return self.message
|
|
16
|
+
|
|
17
|
+
def __repr__(self) -> str:
|
|
18
|
+
return f"<{self.__class__.__name__} message={self.message!r}>"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class OmniaiAuthError(OmniaiError):
|
|
22
|
+
"""Raised when authentication or authorization fails (HTTP 401 / 403)."""
|
|
23
|
+
pass
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class OmniaiPaymentRequiredError(OmniaiError):
|
|
27
|
+
"""Raised when API credit balance is exhausted or payment is required (HTTP 402)."""
|
|
28
|
+
pass
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class OmniaiNotFoundError(OmniaiError):
|
|
32
|
+
"""Raised when a requested resource, model, or task is not found (HTTP 404)."""
|
|
33
|
+
pass
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class OmniaiRateLimitError(OmniaiError):
|
|
37
|
+
"""Raised when request rate limits or concurrency quotas are exceeded (HTTP 429)."""
|
|
38
|
+
|
|
39
|
+
def __init__(
|
|
40
|
+
self,
|
|
41
|
+
message: str,
|
|
42
|
+
retry_after: Optional[float] = None,
|
|
43
|
+
details: Optional[Dict[str, Any]] = None,
|
|
44
|
+
):
|
|
45
|
+
super().__init__(message, details)
|
|
46
|
+
self.retry_after = retry_after
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class OmniaiTimeoutError(OmniaiError):
|
|
50
|
+
"""Raised when a network request, streaming chunk, or task polling times out."""
|
|
51
|
+
pass
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class OmniaiConnectionError(OmniaiError):
|
|
55
|
+
"""Raised when network connectivity fails (DNS resolution, connection refused, broken pipe)."""
|
|
56
|
+
pass
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class OmniaiExecutionError(OmniaiError):
|
|
60
|
+
"""Raised when the OmniAI gateway or upstream LLM provider encounters an execution error (HTTP 5xx / provider failure)."""
|
|
61
|
+
|
|
62
|
+
def __init__(
|
|
63
|
+
self,
|
|
64
|
+
message: str,
|
|
65
|
+
status_code: int = 500,
|
|
66
|
+
details: Optional[Dict[str, Any]] = None,
|
|
67
|
+
):
|
|
68
|
+
super().__init__(message, details)
|
|
69
|
+
self.status_code = status_code
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class OmniaiValidationError(OmniaiError):
|
|
73
|
+
"""Raised when structured outputs or response_model validation fails against expected schema."""
|
|
74
|
+
|
|
75
|
+
def __init__(
|
|
76
|
+
self,
|
|
77
|
+
message: str,
|
|
78
|
+
raw_output: Optional[str] = None,
|
|
79
|
+
details: Optional[Dict[str, Any]] = None,
|
|
80
|
+
):
|
|
81
|
+
super().__init__(message, details)
|
|
82
|
+
self.raw_output = raw_output
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class OmniaiUnsupportedProviderError(OmniaiError):
|
|
86
|
+
"""
|
|
87
|
+
Raised when an unsupported provider is requested.
|
|
88
|
+
The OmniAI SDK strictly supports: 'openai', 'gemini', 'anthropic', and 'vllm'.
|
|
89
|
+
"""
|
|
90
|
+
pass
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
# Standard OpenAI-style & OmniAI naming aliases
|
|
94
|
+
OmniaiAPIError = OmniaiExecutionError
|
|
95
|
+
OmniaiAuthenticationError = OmniaiAuthError
|
|
96
|
+
OmniaiPermissionDeniedError = OmniaiAuthError
|
|
97
|
+
OmniaiBadRequestError = OmniaiValidationError
|
|
98
|
+
|
|
99
|
+
# Aliases with OmniAI / Omni casing
|
|
100
|
+
OmniAIError = OmniaiError
|
|
101
|
+
OmniAIAuthError = OmniaiAuthError
|
|
102
|
+
OmniAIAuthenticationError = OmniaiAuthError
|
|
103
|
+
OmniAIAPIError = OmniaiAPIError
|
|
104
|
+
OmniAIRateLimitError = OmniaiRateLimitError
|
|
105
|
+
OmniAITimeoutError = OmniaiTimeoutError
|
|
106
|
+
OmniAIConnectionError = OmniaiConnectionError
|
|
107
|
+
OmniAIValidationError = OmniaiValidationError
|
|
108
|
+
|
|
109
|
+
OmniError = OmniaiError
|
|
110
|
+
OmniAuthError = OmniaiAuthError
|
|
111
|
+
OmniExecutionError = OmniaiExecutionError
|
|
112
|
+
OmniTimeoutError = OmniaiTimeoutError
|
|
113
|
+
OmniRateLimitError = OmniaiRateLimitError
|
omniai/py.typed
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Marker file for PEP 561 compliance
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""Resource modules for the OmniAI Python SDK."""
|
|
2
|
+
|
|
3
|
+
from omniai.resources.chat import (
|
|
4
|
+
ChatResource,
|
|
5
|
+
AsyncChatResource,
|
|
6
|
+
CompletionsResource,
|
|
7
|
+
AsyncCompletionsResource,
|
|
8
|
+
)
|
|
9
|
+
from omniai.resources.models import ModelsResource, AsyncModelsResource
|
|
10
|
+
from omniai.resources.tasks import TasksResource, AsyncTasksResource
|
|
11
|
+
from omniai.resources.livekit import LiveKitResource, AsyncLiveKitResource
|
|
12
|
+
from omniai.resources.router import RouterEngine
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"ChatResource",
|
|
16
|
+
"AsyncChatResource",
|
|
17
|
+
"CompletionsResource",
|
|
18
|
+
"AsyncCompletionsResource",
|
|
19
|
+
"ModelsResource",
|
|
20
|
+
"AsyncModelsResource",
|
|
21
|
+
"TasksResource",
|
|
22
|
+
"AsyncTasksResource",
|
|
23
|
+
"LiveKitResource",
|
|
24
|
+
"AsyncLiveKitResource",
|
|
25
|
+
"RouterEngine",
|
|
26
|
+
]
|