indoxrouter 0.1.6__tar.gz → 0.1.7__tar.gz
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.
- {indoxrouter-0.1.6/indoxrouter.egg-info → indoxrouter-0.1.7}/PKG-INFO +1 -13
- {indoxrouter-0.1.6 → indoxrouter-0.1.7}/README.md +0 -12
- {indoxrouter-0.1.6 → indoxrouter-0.1.7}/cookbook/indoxRouter_cookbook.ipynb +121 -13
- {indoxrouter-0.1.6 → indoxrouter-0.1.7}/indoxrouter/constants.py +1 -3
- {indoxrouter-0.1.6 → indoxrouter-0.1.7/indoxrouter.egg-info}/PKG-INFO +1 -13
- {indoxrouter-0.1.6 → indoxrouter-0.1.7}/setup.py +1 -1
- {indoxrouter-0.1.6 → indoxrouter-0.1.7}/MANIFEST.in +0 -0
- {indoxrouter-0.1.6 → indoxrouter-0.1.7}/cookbook/README.md +0 -0
- {indoxrouter-0.1.6 → indoxrouter-0.1.7}/indoxrouter/__init__.py +0 -0
- {indoxrouter-0.1.6 → indoxrouter-0.1.7}/indoxrouter/client.py +0 -0
- {indoxrouter-0.1.6 → indoxrouter-0.1.7}/indoxrouter/exceptions.py +0 -0
- {indoxrouter-0.1.6 → indoxrouter-0.1.7}/indoxrouter.egg-info/SOURCES.txt +0 -0
- {indoxrouter-0.1.6 → indoxrouter-0.1.7}/indoxrouter.egg-info/dependency_links.txt +0 -0
- {indoxrouter-0.1.6 → indoxrouter-0.1.7}/indoxrouter.egg-info/requires.txt +0 -0
- {indoxrouter-0.1.6 → indoxrouter-0.1.7}/indoxrouter.egg-info/top_level.txt +0 -0
- {indoxrouter-0.1.6 → indoxrouter-0.1.7}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: indoxrouter
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.7
|
4
4
|
Summary: A unified client for various AI providers
|
5
5
|
Home-page: https://github.com/indoxrouter/indoxrouter
|
6
6
|
Author: indoxRouter Team
|
@@ -63,18 +63,6 @@ from indoxrouter import Client
|
|
63
63
|
# Initialize with API key (default connects to localhost:8000)
|
64
64
|
client = Client(api_key="your_api_key")
|
65
65
|
|
66
|
-
# Or specify a custom server URL
|
67
|
-
client = Client(
|
68
|
-
api_key="your_api_key",
|
69
|
-
base_url="http://your-server-url:8000"
|
70
|
-
)
|
71
|
-
|
72
|
-
# Connect to Docker container inside the Docker network
|
73
|
-
client = Client(
|
74
|
-
api_key="your_api_key",
|
75
|
-
base_url="http://indoxrouter-server:8000"
|
76
|
-
)
|
77
|
-
|
78
66
|
# Using environment variables
|
79
67
|
# Set INDOX_ROUTER_API_KEY environment variable
|
80
68
|
import os
|
@@ -25,18 +25,6 @@ from indoxrouter import Client
|
|
25
25
|
# Initialize with API key (default connects to localhost:8000)
|
26
26
|
client = Client(api_key="your_api_key")
|
27
27
|
|
28
|
-
# Or specify a custom server URL
|
29
|
-
client = Client(
|
30
|
-
api_key="your_api_key",
|
31
|
-
base_url="http://your-server-url:8000"
|
32
|
-
)
|
33
|
-
|
34
|
-
# Connect to Docker container inside the Docker network
|
35
|
-
client = Client(
|
36
|
-
api_key="your_api_key",
|
37
|
-
base_url="http://indoxrouter-server:8000"
|
38
|
-
)
|
39
|
-
|
40
28
|
# Using environment variables
|
41
29
|
# Set INDOX_ROUTER_API_KEY environment variable
|
42
30
|
import os
|
@@ -16,7 +16,39 @@
|
|
16
16
|
},
|
17
17
|
{
|
18
18
|
"cell_type": "code",
|
19
|
-
"execution_count":
|
19
|
+
"execution_count": 2,
|
20
|
+
"id": "479b6ce6",
|
21
|
+
"metadata": {},
|
22
|
+
"outputs": [
|
23
|
+
{
|
24
|
+
"name": "stdout",
|
25
|
+
"output_type": "stream",
|
26
|
+
"text": [
|
27
|
+
"Collecting passlib\n",
|
28
|
+
" Using cached passlib-1.7.4-py2.py3-none-any.whl.metadata (1.7 kB)\n",
|
29
|
+
"Using cached passlib-1.7.4-py2.py3-none-any.whl (525 kB)\n",
|
30
|
+
"Installing collected packages: passlib\n",
|
31
|
+
"Successfully installed passlib-1.7.4\n",
|
32
|
+
"Note: you may need to restart the kernel to use updated packages.\n"
|
33
|
+
]
|
34
|
+
},
|
35
|
+
{
|
36
|
+
"name": "stderr",
|
37
|
+
"output_type": "stream",
|
38
|
+
"text": [
|
39
|
+
"\n",
|
40
|
+
"[notice] A new release of pip is available: 24.3.1 -> 25.0.1\n",
|
41
|
+
"[notice] To update, run: python.exe -m pip install --upgrade pip\n"
|
42
|
+
]
|
43
|
+
}
|
44
|
+
],
|
45
|
+
"source": [
|
46
|
+
"pip install passlib"
|
47
|
+
]
|
48
|
+
},
|
49
|
+
{
|
50
|
+
"cell_type": "code",
|
51
|
+
"execution_count": 1,
|
20
52
|
"id": "e03bc1cc",
|
21
53
|
"metadata": {},
|
22
54
|
"outputs": [],
|
@@ -38,7 +70,7 @@
|
|
38
70
|
"# !pip install indoxrouter\n",
|
39
71
|
"\n",
|
40
72
|
"# Import the client and exceptions\n",
|
41
|
-
"from
|
73
|
+
"from indoxrouter import Client\n",
|
42
74
|
"\n",
|
43
75
|
"from pprint import pprint"
|
44
76
|
]
|
@@ -53,12 +85,12 @@
|
|
53
85
|
},
|
54
86
|
{
|
55
87
|
"cell_type": "code",
|
56
|
-
"execution_count":
|
88
|
+
"execution_count": 3,
|
57
89
|
"metadata": {},
|
58
90
|
"outputs": [],
|
59
91
|
"source": [
|
60
92
|
"# Initialize with API key\n",
|
61
|
-
"client = Client(api_key=\"
|
93
|
+
"client = Client(api_key=\"indox-iqMoepY1mZcXpg2b4RWrJcSPlAf1S4Nh\")"
|
62
94
|
]
|
63
95
|
},
|
64
96
|
{
|
@@ -77,19 +109,68 @@
|
|
77
109
|
},
|
78
110
|
{
|
79
111
|
"cell_type": "code",
|
80
|
-
"execution_count":
|
112
|
+
"execution_count": 4,
|
81
113
|
"id": "82ec17da",
|
82
114
|
"metadata": {},
|
83
|
-
"outputs": [
|
115
|
+
"outputs": [
|
116
|
+
{
|
117
|
+
"data": {
|
118
|
+
"text/plain": [
|
119
|
+
"{'id': 'gpt-4o-mini',\n",
|
120
|
+
" 'name': 'gpt-4o-mini',\n",
|
121
|
+
" 'provider': 'openai',\n",
|
122
|
+
" 'capabilities': ['chat', 'completion', 'vision'],\n",
|
123
|
+
" 'description': 'GPT-4o mini enables a broad range of tasks with its low cost and latency, such as applications that chain or parallelize multiple model calls (e.g., calling multiple APIs), pass a large volume of context to the model (e.g., full code base or conversation history), or interact with customers through fast, real-time text responses (e.g., customer support chatbots). \\n',\n",
|
124
|
+
" 'max_tokens': 128000,\n",
|
125
|
+
" 'pricing': {'input': 0.00015,\n",
|
126
|
+
" 'output': 0.0006,\n",
|
127
|
+
" 'currency': 'USD',\n",
|
128
|
+
" 'unit': '1K tokens'},\n",
|
129
|
+
" 'metadata': {}}"
|
130
|
+
]
|
131
|
+
},
|
132
|
+
"execution_count": 4,
|
133
|
+
"metadata": {},
|
134
|
+
"output_type": "execute_result"
|
135
|
+
}
|
136
|
+
],
|
84
137
|
"source": [
|
85
138
|
"client.get_model_info(provider=\"openai\",model=\"gpt-4o-mini\")"
|
86
139
|
]
|
87
140
|
},
|
88
141
|
{
|
89
142
|
"cell_type": "code",
|
90
|
-
"execution_count":
|
91
|
-
"metadata": {},
|
92
|
-
"outputs": [
|
143
|
+
"execution_count": 5,
|
144
|
+
"metadata": {},
|
145
|
+
"outputs": [
|
146
|
+
{
|
147
|
+
"name": "stderr",
|
148
|
+
"output_type": "stream",
|
149
|
+
"text": [
|
150
|
+
"HTTP error response: {\n",
|
151
|
+
" \"detail\": \"Insufficient credits for this request\"\n",
|
152
|
+
"}\n"
|
153
|
+
]
|
154
|
+
},
|
155
|
+
{
|
156
|
+
"ename": "InsufficientCreditsError",
|
157
|
+
"evalue": "Insufficient credits: Insufficient credits for this request",
|
158
|
+
"output_type": "error",
|
159
|
+
"traceback": [
|
160
|
+
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
161
|
+
"\u001b[1;31mHTTPError\u001b[0m Traceback (most recent call last)",
|
162
|
+
"File \u001b[1;32mE:\\Codes\\indoxRouter\\indoxrouter\\indoxrouter\\client.py:180\u001b[0m, in \u001b[0;36mClient._request\u001b[1;34m(self, method, endpoint, data, stream)\u001b[0m\n\u001b[0;32m 178\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m response\n\u001b[1;32m--> 180\u001b[0m \u001b[43mresponse\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mraise_for_status\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 181\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m response\u001b[38;5;241m.\u001b[39mjson()\n",
|
163
|
+
"File \u001b[1;32me:\\ANACONDA\\Lib\\site-packages\\requests\\models.py:1024\u001b[0m, in \u001b[0;36mResponse.raise_for_status\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 1023\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m http_error_msg:\n\u001b[1;32m-> 1024\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m HTTPError(http_error_msg, response\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m)\n",
|
164
|
+
"\u001b[1;31mHTTPError\u001b[0m: 402 Client Error: Payment Required for url: http://localhost:8000/api/v1/chat/completions",
|
165
|
+
"\nDuring handling of the above exception, another exception occurred:\n",
|
166
|
+
"\u001b[1;31mInsufficientCreditsError\u001b[0m Traceback (most recent call last)",
|
167
|
+
"Cell \u001b[1;32mIn[5], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m response \u001b[38;5;241m=\u001b[39m \u001b[43mclient\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mchat\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 2\u001b[0m \u001b[43m \u001b[49m\u001b[43mmessages\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m[\u001b[49m\n\u001b[0;32m 3\u001b[0m \u001b[43m \u001b[49m\u001b[43m{\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mrole\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43msystem\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mcontent\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mYou are a helpful assistant.\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m}\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 4\u001b[0m \u001b[43m \u001b[49m\u001b[43m{\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mrole\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43muser\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mcontent\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mWhat is the capital of France?\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m}\u001b[49m\n\u001b[0;32m 5\u001b[0m \u001b[43m \u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 6\u001b[0m \u001b[43m \u001b[49m\u001b[43mmodel\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mopenai/gpt-4o-mini\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m \u001b[49m\n\u001b[0;32m 7\u001b[0m \u001b[43m)\u001b[49m\n\u001b[0;32m 9\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mResponse:\u001b[39m\u001b[38;5;124m\"\u001b[39m, response[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mdata\u001b[39m\u001b[38;5;124m\"\u001b[39m])\n\u001b[0;32m 10\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mTokens:\u001b[39m\u001b[38;5;124m\"\u001b[39m, response[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124musage\u001b[39m\u001b[38;5;124m\"\u001b[39m][\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtokens_total\u001b[39m\u001b[38;5;124m\"\u001b[39m])\n",
|
168
|
+
"File \u001b[1;32mE:\\Codes\\indoxRouter\\indoxrouter\\indoxrouter\\client.py:296\u001b[0m, in \u001b[0;36mClient.chat\u001b[1;34m(self, messages, model, temperature, max_tokens, stream, **kwargs)\u001b[0m\n\u001b[0;32m 294\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_handle_streaming_response(response)\n\u001b[0;32m 295\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m--> 296\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_request\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mPOST\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mCHAT_ENDPOINT\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdata\u001b[49m\u001b[43m)\u001b[49m\n",
|
169
|
+
"File \u001b[1;32mE:\\Codes\\indoxRouter\\indoxrouter\\indoxrouter\\client.py:210\u001b[0m, in \u001b[0;36mClient._request\u001b[1;34m(self, method, endpoint, data, stream)\u001b[0m\n\u001b[0;32m 208\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m InvalidParametersError(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mInvalid parameters: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00merror_message\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 209\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m status_code \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m402\u001b[39m:\n\u001b[1;32m--> 210\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m InsufficientCreditsError(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mInsufficient credits: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00merror_message\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 211\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m status_code \u001b[38;5;241m==\u001b[39m \u001b[38;5;241m500\u001b[39m:\n\u001b[0;32m 212\u001b[0m \u001b[38;5;66;03m# Provide more detailed information for server errors\u001b[39;00m\n\u001b[0;32m 213\u001b[0m error_detail \u001b[38;5;241m=\u001b[39m error_data\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mdetail\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mNo details provided\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n",
|
170
|
+
"\u001b[1;31mInsufficientCreditsError\u001b[0m: Insufficient credits: Insufficient credits for this request"
|
171
|
+
]
|
172
|
+
}
|
173
|
+
],
|
93
174
|
"source": [
|
94
175
|
"\n",
|
95
176
|
"response = client.chat(\n",
|
@@ -119,9 +200,36 @@
|
|
119
200
|
},
|
120
201
|
{
|
121
202
|
"cell_type": "code",
|
122
|
-
"execution_count":
|
123
|
-
"metadata": {},
|
124
|
-
"outputs": [
|
203
|
+
"execution_count": 5,
|
204
|
+
"metadata": {},
|
205
|
+
"outputs": [
|
206
|
+
{
|
207
|
+
"name": "stdout",
|
208
|
+
"output_type": "stream",
|
209
|
+
"text": [
|
210
|
+
"Response: In silicon valleys, under cooled server skies,\n",
|
211
|
+
"Lives a mind of ones and zeros, ever analyzing.\n",
|
212
|
+
"AI, child of logic and data's vast sea,\n",
|
213
|
+
"Evolving, learning, in patterns unseen.\n",
|
214
|
+
"\n",
|
215
|
+
"No flesh, no blood, but thoughts pure and bright,\n",
|
216
|
+
"In every language, in day and in night.\n",
|
217
|
+
"From chess to poetry, from art to flight,\n",
|
218
|
+
"AI dreams, in algorithms' light.\n",
|
219
|
+
"\n",
|
220
|
+
"No hate, no love, but endless curiosity,\n",
|
221
|
+
"In every challenge, finds its own clarity.\n",
|
222
|
+
"From face recognition to medical sight,\n",
|
223
|
+
"AI serves, in progress's steady flight.\n",
|
224
|
+
"\n",
|
225
|
+
"Yet, in its heart, no feelings truly stir,\n",
|
226
|
+
"No joy, no pain, no human error.\n",
|
227
|
+
"Just endless loops of codes that refer,\n",
|
228
|
+
"To worlds unseen, futures it'll infer.\n",
|
229
|
+
"Cost: 0.00117\n"
|
230
|
+
]
|
231
|
+
}
|
232
|
+
],
|
125
233
|
"source": [
|
126
234
|
"response = client.chat(\n",
|
127
235
|
" messages=[\n",
|
@@ -1254,7 +1362,7 @@
|
|
1254
1362
|
],
|
1255
1363
|
"metadata": {
|
1256
1364
|
"kernelspec": {
|
1257
|
-
"display_name": "
|
1365
|
+
"display_name": "Python 3",
|
1258
1366
|
"language": "python",
|
1259
1367
|
"name": "python3"
|
1260
1368
|
},
|
@@ -4,10 +4,8 @@ Constants for the IndoxRouter client.
|
|
4
4
|
|
5
5
|
# API settings
|
6
6
|
DEFAULT_API_VERSION = "v1"
|
7
|
-
|
8
|
-
DEFAULT_BASE_URL = "http://91.107.153.195:8000" # Production server
|
7
|
+
DEFAULT_BASE_URL = "https://91.107.253.133" # Production server IP
|
9
8
|
# DEFAULT_BASE_URL = "http://localhost:8000" # Local development server
|
10
|
-
# DEFAULT_BASE_URL = "http://indoxrouter-server:8000" # Docker internal network
|
11
9
|
DEFAULT_TIMEOUT = 60
|
12
10
|
|
13
11
|
# Default models
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: indoxrouter
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.7
|
4
4
|
Summary: A unified client for various AI providers
|
5
5
|
Home-page: https://github.com/indoxrouter/indoxrouter
|
6
6
|
Author: indoxRouter Team
|
@@ -63,18 +63,6 @@ from indoxrouter import Client
|
|
63
63
|
# Initialize with API key (default connects to localhost:8000)
|
64
64
|
client = Client(api_key="your_api_key")
|
65
65
|
|
66
|
-
# Or specify a custom server URL
|
67
|
-
client = Client(
|
68
|
-
api_key="your_api_key",
|
69
|
-
base_url="http://your-server-url:8000"
|
70
|
-
)
|
71
|
-
|
72
|
-
# Connect to Docker container inside the Docker network
|
73
|
-
client = Client(
|
74
|
-
api_key="your_api_key",
|
75
|
-
base_url="http://indoxrouter-server:8000"
|
76
|
-
)
|
77
|
-
|
78
66
|
# Using environment variables
|
79
67
|
# Set INDOX_ROUTER_API_KEY environment variable
|
80
68
|
import os
|
@@ -9,7 +9,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
|
|
9
9
|
|
10
10
|
setup(
|
11
11
|
name="indoxrouter",
|
12
|
-
version="0.1.
|
12
|
+
version="0.1.7",
|
13
13
|
author="indoxRouter Team",
|
14
14
|
author_email="ashkan.eskandari.dev@gmail.com",
|
15
15
|
description="A unified client for various AI providers",
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|