hedgequantx 2.6.163 → 2.7.1
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.
- package/README.md +15 -88
- package/bin/cli.js +0 -11
- package/dist/lib/api.jsc +0 -0
- package/dist/lib/api2.jsc +0 -0
- package/dist/lib/core.jsc +0 -0
- package/dist/lib/core2.jsc +0 -0
- package/dist/lib/data.js +1 -1
- package/dist/lib/data.jsc +0 -0
- package/dist/lib/data2.jsc +0 -0
- package/dist/lib/decoder.jsc +0 -0
- package/dist/lib/m/mod1.jsc +0 -0
- package/dist/lib/m/mod2.jsc +0 -0
- package/dist/lib/n/r1.jsc +0 -0
- package/dist/lib/n/r2.jsc +0 -0
- package/dist/lib/n/r3.jsc +0 -0
- package/dist/lib/n/r4.jsc +0 -0
- package/dist/lib/n/r5.jsc +0 -0
- package/dist/lib/n/r6.jsc +0 -0
- package/dist/lib/n/r7.jsc +0 -0
- package/dist/lib/o/util1.jsc +0 -0
- package/dist/lib/o/util2.jsc +0 -0
- package/package.json +8 -5
- package/src/app.js +40 -162
- package/src/config/constants.js +31 -33
- package/src/config/propfirms.js +13 -217
- package/src/config/settings.js +0 -43
- package/src/lib/api.js +198 -0
- package/src/lib/api2.js +353 -0
- package/src/lib/core.js +539 -0
- package/src/lib/core2.js +341 -0
- package/src/lib/data.js +555 -0
- package/src/lib/data2.js +492 -0
- package/src/lib/decoder.js +599 -0
- package/src/lib/m/s1.js +804 -0
- package/src/lib/m/s2.js +34 -0
- package/src/lib/n/r1.js +454 -0
- package/src/lib/n/r2.js +514 -0
- package/src/lib/n/r3.js +631 -0
- package/src/lib/n/r4.js +401 -0
- package/src/lib/n/r5.js +335 -0
- package/src/lib/n/r6.js +425 -0
- package/src/lib/n/r7.js +530 -0
- package/src/lib/o/l1.js +44 -0
- package/src/lib/o/l2.js +427 -0
- package/src/lib/python-bridge.js +206 -0
- package/src/menus/connect.js +14 -176
- package/src/menus/dashboard.js +65 -110
- package/src/pages/accounts.js +18 -18
- package/src/pages/algo/copy-trading.js +210 -240
- package/src/pages/algo/index.js +41 -104
- package/src/pages/algo/one-account.js +386 -33
- package/src/pages/algo/ui.js +312 -151
- package/src/pages/orders.js +3 -3
- package/src/pages/positions.js +3 -3
- package/src/pages/stats/chart.js +74 -0
- package/src/pages/stats/display.js +228 -0
- package/src/pages/stats/index.js +236 -0
- package/src/pages/stats/metrics.js +213 -0
- package/src/pages/user.js +6 -6
- package/src/services/hqx-server/constants.js +55 -0
- package/src/services/hqx-server/index.js +401 -0
- package/src/services/hqx-server/latency.js +81 -0
- package/src/services/index.js +12 -3
- package/src/services/rithmic/accounts.js +7 -32
- package/src/services/rithmic/connection.js +1 -204
- package/src/services/rithmic/contracts.js +116 -99
- package/src/services/rithmic/handlers.js +21 -196
- package/src/services/rithmic/index.js +63 -120
- package/src/services/rithmic/market.js +31 -0
- package/src/services/rithmic/orders.js +5 -111
- package/src/services/rithmic/protobuf.js +384 -138
- package/src/services/session.js +22 -173
- package/src/ui/box.js +10 -18
- package/src/ui/index.js +1 -3
- package/src/ui/menu.js +1 -1
- package/src/utils/prompts.js +2 -2
- package/dist/lib/m/s1.js +0 -1
- package/src/menus/ai-agent-connect.js +0 -181
- package/src/menus/ai-agent-models.js +0 -219
- package/src/menus/ai-agent-oauth.js +0 -292
- package/src/menus/ai-agent-ui.js +0 -141
- package/src/menus/ai-agent.js +0 -484
- package/src/pages/algo/algo-config.js +0 -195
- package/src/pages/algo/algo-multi.js +0 -801
- package/src/pages/algo/algo-utils.js +0 -58
- package/src/pages/algo/copy-engine.js +0 -449
- package/src/pages/algo/custom-strategy.js +0 -459
- package/src/pages/algo/logger.js +0 -245
- package/src/pages/algo/smart-logs-data.js +0 -218
- package/src/pages/algo/smart-logs.js +0 -387
- package/src/pages/algo/ui-constants.js +0 -144
- package/src/pages/algo/ui-summary.js +0 -184
- package/src/pages/stats-calculations.js +0 -191
- package/src/pages/stats-ui.js +0 -381
- package/src/pages/stats.js +0 -339
- package/src/services/ai/client-analysis.js +0 -194
- package/src/services/ai/client-models.js +0 -333
- package/src/services/ai/client.js +0 -343
- package/src/services/ai/index.js +0 -384
- package/src/services/ai/oauth-anthropic.js +0 -265
- package/src/services/ai/oauth-gemini.js +0 -223
- package/src/services/ai/oauth-iflow.js +0 -269
- package/src/services/ai/oauth-openai.js +0 -233
- package/src/services/ai/oauth-qwen.js +0 -279
- package/src/services/ai/providers/direct-providers.js +0 -323
- package/src/services/ai/providers/index.js +0 -62
- package/src/services/ai/providers/other-providers.js +0 -104
- package/src/services/ai/proxy-install.js +0 -249
- package/src/services/ai/proxy-manager.js +0 -494
- package/src/services/ai/proxy-remote.js +0 -161
- package/src/services/ai/strategy-supervisor.js +0 -1312
- package/src/services/ai/supervisor-data.js +0 -195
- package/src/services/ai/supervisor-optimize.js +0 -215
- package/src/services/ai/supervisor-sync.js +0 -178
- package/src/services/ai/supervisor-utils.js +0 -158
- package/src/services/ai/supervisor.js +0 -484
- package/src/services/ai/validation.js +0 -250
- package/src/services/hqx-server-events.js +0 -110
- package/src/services/hqx-server-handlers.js +0 -217
- package/src/services/hqx-server-latency.js +0 -136
- package/src/services/hqx-server.js +0 -403
- package/src/services/position-constants.js +0 -28
- package/src/services/position-exit-logic.js +0 -174
- package/src/services/position-manager.js +0 -438
- package/src/services/position-momentum.js +0 -206
- package/src/services/projectx/accounts.js +0 -142
- package/src/services/projectx/index.js +0 -443
- package/src/services/projectx/market.js +0 -172
- package/src/services/projectx/stats.js +0 -110
- package/src/services/projectx/trading.js +0 -180
- package/src/services/rithmic/latency-tracker.js +0 -182
- package/src/services/rithmic/market-data-decoders.js +0 -229
- package/src/services/rithmic/market-data.js +0 -272
- package/src/services/rithmic/orders-fast.js +0 -246
- package/src/services/rithmic/proto-decoders.js +0 -403
- package/src/services/rithmic/specs.js +0 -146
- package/src/services/rithmic/trade-history.js +0 -254
- package/src/services/session-history.js +0 -475
- package/src/services/strategy/hft-signal-calc.js +0 -147
- package/src/services/strategy/hft-tick.js +0 -407
- package/src/services/strategy/recovery-math.js +0 -402
- package/src/services/tradovate/constants.js +0 -109
- package/src/services/tradovate/index.js +0 -392
- package/src/services/tradovate/market.js +0 -47
- package/src/services/tradovate/orders.js +0 -145
- package/src/services/tradovate/websocket.js +0 -97
|
@@ -1,279 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Qwen OAuth Authentication (Device Flow)
|
|
3
|
-
*
|
|
4
|
-
* Implements OAuth 2.0 Device Authorization Grant for Qwen Chat subscription.
|
|
5
|
-
* Based on the public OAuth flow used by Qwen Code CLI.
|
|
6
|
-
*
|
|
7
|
-
* Data source: Qwen OAuth API (https://chat.qwen.ai/api/v1/oauth2)
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
const crypto = require('crypto');
|
|
11
|
-
const https = require('https');
|
|
12
|
-
|
|
13
|
-
// Public OAuth Client ID (from Qwen CLI)
|
|
14
|
-
const CLIENT_ID = 'f0304373b74a44d2b584a3fb70ca9e56';
|
|
15
|
-
const DEVICE_CODE_URL = 'https://chat.qwen.ai/api/v1/oauth2/device/code';
|
|
16
|
-
const TOKEN_URL = 'https://chat.qwen.ai/api/v1/oauth2/token';
|
|
17
|
-
const SCOPES = 'openid profile email model.completion';
|
|
18
|
-
const GRANT_TYPE = 'urn:ietf:params:oauth:grant-type:device_code';
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Generate PKCE code verifier and challenge
|
|
22
|
-
* @returns {Object} { verifier: string, challenge: string }
|
|
23
|
-
*/
|
|
24
|
-
const generatePKCE = () => {
|
|
25
|
-
const verifier = crypto.randomBytes(32)
|
|
26
|
-
.toString('base64')
|
|
27
|
-
.replace(/\+/g, '-')
|
|
28
|
-
.replace(/\//g, '_')
|
|
29
|
-
.replace(/=/g, '');
|
|
30
|
-
|
|
31
|
-
const challenge = crypto.createHash('sha256')
|
|
32
|
-
.update(verifier)
|
|
33
|
-
.digest('base64')
|
|
34
|
-
.replace(/\+/g, '-')
|
|
35
|
-
.replace(/\//g, '_')
|
|
36
|
-
.replace(/=/g, '');
|
|
37
|
-
|
|
38
|
-
return { verifier, challenge };
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Make HTTPS request
|
|
43
|
-
*/
|
|
44
|
-
const makeRequest = (urlStr, options) => {
|
|
45
|
-
return new Promise((resolve, reject) => {
|
|
46
|
-
const url = new URL(urlStr);
|
|
47
|
-
const req = https.request({
|
|
48
|
-
hostname: url.hostname,
|
|
49
|
-
port: url.port || 443,
|
|
50
|
-
path: url.pathname + url.search,
|
|
51
|
-
method: options.method || 'POST',
|
|
52
|
-
headers: options.headers || {}
|
|
53
|
-
}, (res) => {
|
|
54
|
-
let data = '';
|
|
55
|
-
res.on('data', chunk => data += chunk);
|
|
56
|
-
res.on('end', () => {
|
|
57
|
-
try {
|
|
58
|
-
const json = JSON.parse(data);
|
|
59
|
-
if (res.statusCode >= 200 && res.statusCode < 300) {
|
|
60
|
-
resolve(json);
|
|
61
|
-
} else {
|
|
62
|
-
resolve({ ...json, statusCode: res.statusCode }); // Return error response for polling
|
|
63
|
-
}
|
|
64
|
-
} catch (e) {
|
|
65
|
-
reject(new Error(`Invalid JSON response: ${data.substring(0, 200)}`));
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
req.on('error', reject);
|
|
71
|
-
|
|
72
|
-
if (options.body) {
|
|
73
|
-
req.write(options.body);
|
|
74
|
-
}
|
|
75
|
-
req.end();
|
|
76
|
-
});
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Initiate device authorization flow
|
|
81
|
-
* @returns {Promise<Object>} { deviceCode, userCode, verificationUri, verificationUriComplete, expiresIn, interval, verifier }
|
|
82
|
-
*/
|
|
83
|
-
const initiateDeviceFlow = async () => {
|
|
84
|
-
try {
|
|
85
|
-
const pkce = generatePKCE();
|
|
86
|
-
|
|
87
|
-
const body = new URLSearchParams({
|
|
88
|
-
client_id: CLIENT_ID,
|
|
89
|
-
scope: SCOPES,
|
|
90
|
-
code_challenge: pkce.challenge,
|
|
91
|
-
code_challenge_method: 'S256'
|
|
92
|
-
}).toString();
|
|
93
|
-
|
|
94
|
-
const response = await makeRequest(DEVICE_CODE_URL, {
|
|
95
|
-
method: 'POST',
|
|
96
|
-
headers: {
|
|
97
|
-
'Content-Type': 'application/x-www-form-urlencoded',
|
|
98
|
-
'Accept': 'application/json'
|
|
99
|
-
},
|
|
100
|
-
body
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
if (!response.device_code) {
|
|
104
|
-
return {
|
|
105
|
-
type: 'failed',
|
|
106
|
-
error: 'Device code not found in response'
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return {
|
|
111
|
-
type: 'success',
|
|
112
|
-
deviceCode: response.device_code,
|
|
113
|
-
userCode: response.user_code,
|
|
114
|
-
verificationUri: response.verification_uri,
|
|
115
|
-
verificationUriComplete: response.verification_uri_complete,
|
|
116
|
-
expiresIn: response.expires_in,
|
|
117
|
-
interval: response.interval || 5,
|
|
118
|
-
verifier: pkce.verifier
|
|
119
|
-
};
|
|
120
|
-
} catch (error) {
|
|
121
|
-
return {
|
|
122
|
-
type: 'failed',
|
|
123
|
-
error: error.message
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Poll for token (single attempt)
|
|
130
|
-
* @param {string} deviceCode - Device code from initiateDeviceFlow
|
|
131
|
-
* @param {string} verifier - PKCE code verifier
|
|
132
|
-
* @returns {Promise<Object>}
|
|
133
|
-
*/
|
|
134
|
-
const pollForToken = async (deviceCode, verifier) => {
|
|
135
|
-
try {
|
|
136
|
-
const body = new URLSearchParams({
|
|
137
|
-
grant_type: GRANT_TYPE,
|
|
138
|
-
client_id: CLIENT_ID,
|
|
139
|
-
device_code: deviceCode,
|
|
140
|
-
code_verifier: verifier
|
|
141
|
-
}).toString();
|
|
142
|
-
|
|
143
|
-
const response = await makeRequest(TOKEN_URL, {
|
|
144
|
-
method: 'POST',
|
|
145
|
-
headers: {
|
|
146
|
-
'Content-Type': 'application/x-www-form-urlencoded',
|
|
147
|
-
'Accept': 'application/json'
|
|
148
|
-
},
|
|
149
|
-
body
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
// Check for polling errors (RFC 8628)
|
|
153
|
-
if (response.error) {
|
|
154
|
-
switch (response.error) {
|
|
155
|
-
case 'authorization_pending':
|
|
156
|
-
return { type: 'pending' };
|
|
157
|
-
case 'slow_down':
|
|
158
|
-
return { type: 'slow_down' };
|
|
159
|
-
case 'expired_token':
|
|
160
|
-
return { type: 'failed', error: 'Device code expired. Please restart authentication.' };
|
|
161
|
-
case 'access_denied':
|
|
162
|
-
return { type: 'failed', error: 'Authorization denied by user.' };
|
|
163
|
-
default:
|
|
164
|
-
return { type: 'failed', error: response.error_description || response.error };
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// Success
|
|
169
|
-
if (response.access_token) {
|
|
170
|
-
return {
|
|
171
|
-
type: 'success',
|
|
172
|
-
access: response.access_token,
|
|
173
|
-
refresh: response.refresh_token,
|
|
174
|
-
resourceUrl: response.resource_url,
|
|
175
|
-
expires: Date.now() + (response.expires_in * 1000)
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
return { type: 'pending' };
|
|
180
|
-
} catch (error) {
|
|
181
|
-
return {
|
|
182
|
-
type: 'failed',
|
|
183
|
-
error: error.message
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Refresh access token using refresh token
|
|
190
|
-
* @param {string} refreshTokenValue - The refresh token
|
|
191
|
-
* @returns {Promise<Object>}
|
|
192
|
-
*/
|
|
193
|
-
const refreshToken = async (refreshTokenValue) => {
|
|
194
|
-
try {
|
|
195
|
-
const body = new URLSearchParams({
|
|
196
|
-
grant_type: 'refresh_token',
|
|
197
|
-
refresh_token: refreshTokenValue,
|
|
198
|
-
client_id: CLIENT_ID
|
|
199
|
-
}).toString();
|
|
200
|
-
|
|
201
|
-
const response = await makeRequest(TOKEN_URL, {
|
|
202
|
-
method: 'POST',
|
|
203
|
-
headers: {
|
|
204
|
-
'Content-Type': 'application/x-www-form-urlencoded',
|
|
205
|
-
'Accept': 'application/json'
|
|
206
|
-
},
|
|
207
|
-
body
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
if (response.error) {
|
|
211
|
-
return {
|
|
212
|
-
type: 'failed',
|
|
213
|
-
error: response.error_description || response.error
|
|
214
|
-
};
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
return {
|
|
218
|
-
type: 'success',
|
|
219
|
-
access: response.access_token,
|
|
220
|
-
refresh: response.refresh_token,
|
|
221
|
-
resourceUrl: response.resource_url,
|
|
222
|
-
expires: Date.now() + (response.expires_in * 1000)
|
|
223
|
-
};
|
|
224
|
-
} catch (error) {
|
|
225
|
-
return {
|
|
226
|
-
type: 'failed',
|
|
227
|
-
error: error.message
|
|
228
|
-
};
|
|
229
|
-
}
|
|
230
|
-
};
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Get valid access token (refresh if expired)
|
|
234
|
-
* @param {Object} oauthData - OAuth data { access, refresh, expires }
|
|
235
|
-
* @returns {Promise<Object>}
|
|
236
|
-
*/
|
|
237
|
-
const getValidToken = async (oauthData) => {
|
|
238
|
-
if (!oauthData || !oauthData.refresh) {
|
|
239
|
-
return null;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
const expirationBuffer = 5 * 60 * 1000; // 5 minutes
|
|
243
|
-
if (oauthData.expires && oauthData.expires > Date.now() + expirationBuffer) {
|
|
244
|
-
return {
|
|
245
|
-
...oauthData,
|
|
246
|
-
refreshed: false
|
|
247
|
-
};
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
const result = await refreshToken(oauthData.refresh);
|
|
251
|
-
if (result.type === 'success') {
|
|
252
|
-
return {
|
|
253
|
-
access: result.access,
|
|
254
|
-
refresh: result.refresh,
|
|
255
|
-
expires: result.expires,
|
|
256
|
-
refreshed: true
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
return null;
|
|
261
|
-
};
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* Check if credentials are OAuth tokens
|
|
265
|
-
*/
|
|
266
|
-
const isOAuthCredentials = (credentials) => {
|
|
267
|
-
return credentials && credentials.oauth && credentials.oauth.refresh;
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
module.exports = {
|
|
271
|
-
CLIENT_ID,
|
|
272
|
-
SCOPES,
|
|
273
|
-
generatePKCE,
|
|
274
|
-
initiateDeviceFlow,
|
|
275
|
-
pollForToken,
|
|
276
|
-
refreshToken,
|
|
277
|
-
getValidToken,
|
|
278
|
-
isOAuthCredentials
|
|
279
|
-
};
|
|
@@ -1,323 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Direct AI Providers Configuration
|
|
3
|
-
* @module services/ai/providers/direct-providers
|
|
4
|
-
*
|
|
5
|
-
* Provider configurations that connect directly to each provider's API
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const DIRECT_PROVIDERS = {
|
|
9
|
-
anthropic: {
|
|
10
|
-
id: 'anthropic',
|
|
11
|
-
name: 'CLAUDE (ANTHROPIC)',
|
|
12
|
-
description: 'Pro/Max or API Key',
|
|
13
|
-
category: 'direct',
|
|
14
|
-
models: [],
|
|
15
|
-
defaultModel: null,
|
|
16
|
-
options: [
|
|
17
|
-
{
|
|
18
|
-
id: 'oauth_max',
|
|
19
|
-
label: 'CLAUDE PRO/MAX (OAUTH)',
|
|
20
|
-
description: ['Login with your Claude subscription', 'Unlimited usage with your plan'],
|
|
21
|
-
fields: ['oauth'],
|
|
22
|
-
authType: 'oauth'
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
id: 'api_key',
|
|
26
|
-
label: 'API KEY (PAY-PER-USE)',
|
|
27
|
-
description: ['Get key at console.anthropic.com', '~$0.10 per trading session'],
|
|
28
|
-
fields: ['apiKey'],
|
|
29
|
-
url: 'https://console.anthropic.com/settings/keys'
|
|
30
|
-
}
|
|
31
|
-
],
|
|
32
|
-
endpoint: 'https://api.anthropic.com/v1'
|
|
33
|
-
},
|
|
34
|
-
|
|
35
|
-
openai: {
|
|
36
|
-
id: 'openai',
|
|
37
|
-
name: 'OPENAI (GPT-4/5)',
|
|
38
|
-
description: 'Plus/Pro or API Key',
|
|
39
|
-
category: 'direct',
|
|
40
|
-
models: [],
|
|
41
|
-
defaultModel: null,
|
|
42
|
-
options: [
|
|
43
|
-
{
|
|
44
|
-
id: 'oauth_plus',
|
|
45
|
-
label: 'PLUS/PRO SUBSCRIPTION (OAUTH)',
|
|
46
|
-
description: ['Login with your ChatGPT account', 'Unlimited with your plan'],
|
|
47
|
-
fields: ['oauth'],
|
|
48
|
-
authType: 'oauth'
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
id: 'api_key',
|
|
52
|
-
label: 'API KEY (PAY-PER-USE)',
|
|
53
|
-
description: ['Get key at platform.openai.com', '~$0.15 per trading session'],
|
|
54
|
-
fields: ['apiKey'],
|
|
55
|
-
url: 'https://platform.openai.com/api-keys'
|
|
56
|
-
}
|
|
57
|
-
],
|
|
58
|
-
endpoint: 'https://api.openai.com/v1'
|
|
59
|
-
},
|
|
60
|
-
|
|
61
|
-
gemini: {
|
|
62
|
-
id: 'gemini',
|
|
63
|
-
name: 'GEMINI (GOOGLE)',
|
|
64
|
-
description: 'Advanced or API Key',
|
|
65
|
-
category: 'direct',
|
|
66
|
-
models: [],
|
|
67
|
-
defaultModel: null,
|
|
68
|
-
options: [
|
|
69
|
-
{
|
|
70
|
-
id: 'oauth_advanced',
|
|
71
|
-
label: 'ADVANCED SUBSCRIPTION (OAUTH)',
|
|
72
|
-
description: ['Login with your Google account', 'Unlimited with your plan'],
|
|
73
|
-
fields: ['oauth'],
|
|
74
|
-
authType: 'oauth'
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
id: 'api_key',
|
|
78
|
-
label: 'API KEY (FREE TIER)',
|
|
79
|
-
description: ['Get key at aistudio.google.com', 'Free tier: 60 requests/min'],
|
|
80
|
-
fields: ['apiKey'],
|
|
81
|
-
url: 'https://aistudio.google.com/apikey'
|
|
82
|
-
}
|
|
83
|
-
],
|
|
84
|
-
endpoint: 'https://generativelanguage.googleapis.com/v1'
|
|
85
|
-
},
|
|
86
|
-
|
|
87
|
-
deepseek: {
|
|
88
|
-
id: 'deepseek',
|
|
89
|
-
name: 'DEEPSEEK',
|
|
90
|
-
description: 'Very cheap & capable',
|
|
91
|
-
category: 'direct',
|
|
92
|
-
models: [],
|
|
93
|
-
defaultModel: null,
|
|
94
|
-
options: [
|
|
95
|
-
{
|
|
96
|
-
id: 'api_key',
|
|
97
|
-
label: 'API KEY (VERY CHEAP)',
|
|
98
|
-
description: ['Get key at platform.deepseek.com', '~$0.02 per trading session'],
|
|
99
|
-
fields: ['apiKey'],
|
|
100
|
-
url: 'https://platform.deepseek.com'
|
|
101
|
-
}
|
|
102
|
-
],
|
|
103
|
-
endpoint: 'https://api.deepseek.com/v1'
|
|
104
|
-
},
|
|
105
|
-
|
|
106
|
-
groq: {
|
|
107
|
-
id: 'groq',
|
|
108
|
-
name: 'GROQ',
|
|
109
|
-
description: 'Ultra fast inference',
|
|
110
|
-
category: 'direct',
|
|
111
|
-
models: [],
|
|
112
|
-
defaultModel: null,
|
|
113
|
-
options: [
|
|
114
|
-
{
|
|
115
|
-
id: 'api_key',
|
|
116
|
-
label: 'API KEY (FREE TIER)',
|
|
117
|
-
description: ['Get key at console.groq.com', 'Generous free tier', 'Ultra low latency'],
|
|
118
|
-
fields: ['apiKey'],
|
|
119
|
-
url: 'https://console.groq.com/keys'
|
|
120
|
-
}
|
|
121
|
-
],
|
|
122
|
-
endpoint: 'https://api.groq.com/openai/v1'
|
|
123
|
-
},
|
|
124
|
-
|
|
125
|
-
xai: {
|
|
126
|
-
id: 'xai',
|
|
127
|
-
name: 'GROK (XAI)',
|
|
128
|
-
description: 'Elon Musk\'s Grok AI',
|
|
129
|
-
category: 'direct',
|
|
130
|
-
models: [],
|
|
131
|
-
defaultModel: null,
|
|
132
|
-
options: [
|
|
133
|
-
{
|
|
134
|
-
id: 'api_key',
|
|
135
|
-
label: 'API KEY',
|
|
136
|
-
description: ['Get key at console.x.ai', 'Grok models from xAI'],
|
|
137
|
-
fields: ['apiKey'],
|
|
138
|
-
url: 'https://console.x.ai'
|
|
139
|
-
}
|
|
140
|
-
],
|
|
141
|
-
endpoint: 'https://api.x.ai/v1'
|
|
142
|
-
},
|
|
143
|
-
|
|
144
|
-
mistral: {
|
|
145
|
-
id: 'mistral',
|
|
146
|
-
name: 'MISTRAL',
|
|
147
|
-
description: 'European AI leader',
|
|
148
|
-
category: 'direct',
|
|
149
|
-
models: [],
|
|
150
|
-
defaultModel: null,
|
|
151
|
-
options: [
|
|
152
|
-
{
|
|
153
|
-
id: 'api_key',
|
|
154
|
-
label: 'API KEY',
|
|
155
|
-
description: ['Get key at console.mistral.ai', 'Fast European models'],
|
|
156
|
-
fields: ['apiKey'],
|
|
157
|
-
url: 'https://console.mistral.ai'
|
|
158
|
-
}
|
|
159
|
-
],
|
|
160
|
-
endpoint: 'https://api.mistral.ai/v1'
|
|
161
|
-
},
|
|
162
|
-
|
|
163
|
-
perplexity: {
|
|
164
|
-
id: 'perplexity',
|
|
165
|
-
name: 'PERPLEXITY',
|
|
166
|
-
description: 'Real-time web search AI',
|
|
167
|
-
category: 'direct',
|
|
168
|
-
models: [],
|
|
169
|
-
defaultModel: null,
|
|
170
|
-
options: [
|
|
171
|
-
{
|
|
172
|
-
id: 'api_key',
|
|
173
|
-
label: 'API KEY',
|
|
174
|
-
description: ['Get key at perplexity.ai/settings/api', 'Real-time market news & data', 'Web search integrated'],
|
|
175
|
-
fields: ['apiKey'],
|
|
176
|
-
url: 'https://www.perplexity.ai/settings/api'
|
|
177
|
-
}
|
|
178
|
-
],
|
|
179
|
-
endpoint: 'https://api.perplexity.ai'
|
|
180
|
-
},
|
|
181
|
-
|
|
182
|
-
together: {
|
|
183
|
-
id: 'together',
|
|
184
|
-
name: 'TOGETHER AI',
|
|
185
|
-
description: 'Open source models, fast & cheap',
|
|
186
|
-
category: 'direct',
|
|
187
|
-
models: [],
|
|
188
|
-
defaultModel: null,
|
|
189
|
-
options: [
|
|
190
|
-
{
|
|
191
|
-
id: 'api_key',
|
|
192
|
-
label: 'API KEY',
|
|
193
|
-
description: ['Get key at api.together.xyz', '100+ open source models', 'Fast inference, good pricing'],
|
|
194
|
-
fields: ['apiKey'],
|
|
195
|
-
url: 'https://api.together.xyz/settings/api-keys'
|
|
196
|
-
}
|
|
197
|
-
],
|
|
198
|
-
endpoint: 'https://api.together.xyz/v1'
|
|
199
|
-
},
|
|
200
|
-
|
|
201
|
-
iflow: {
|
|
202
|
-
id: 'iflow',
|
|
203
|
-
name: 'IFLOW',
|
|
204
|
-
description: 'Subscription (OAuth)',
|
|
205
|
-
category: 'direct',
|
|
206
|
-
models: [],
|
|
207
|
-
defaultModel: null,
|
|
208
|
-
options: [
|
|
209
|
-
{
|
|
210
|
-
id: 'oauth_sub',
|
|
211
|
-
label: 'SUBSCRIPTION (OAUTH)',
|
|
212
|
-
description: ['Login with your iFlow account', 'Access to DeepSeek, Kimi, GLM & more'],
|
|
213
|
-
fields: ['oauth'],
|
|
214
|
-
authType: 'oauth'
|
|
215
|
-
}
|
|
216
|
-
],
|
|
217
|
-
endpoint: 'https://api.iflow.com/v1'
|
|
218
|
-
},
|
|
219
|
-
|
|
220
|
-
qwen: {
|
|
221
|
-
id: 'qwen',
|
|
222
|
-
name: 'QWEN (ALIBABA)',
|
|
223
|
-
description: 'Chat subscription or API Key',
|
|
224
|
-
category: 'direct',
|
|
225
|
-
models: [],
|
|
226
|
-
defaultModel: null,
|
|
227
|
-
options: [
|
|
228
|
-
{
|
|
229
|
-
id: 'oauth_chat',
|
|
230
|
-
label: 'CHAT SUBSCRIPTION (OAUTH)',
|
|
231
|
-
description: ['Login with your Qwen account', 'Unlimited with your plan'],
|
|
232
|
-
fields: ['oauth'],
|
|
233
|
-
authType: 'oauth'
|
|
234
|
-
},
|
|
235
|
-
{
|
|
236
|
-
id: 'api_key',
|
|
237
|
-
label: 'API KEY (DASHSCOPE)',
|
|
238
|
-
description: ['Get key at dashscope.aliyun.com', 'Qwen2.5 models', 'Very competitive pricing'],
|
|
239
|
-
fields: ['apiKey'],
|
|
240
|
-
url: 'https://dashscope.console.aliyun.com/apiKey'
|
|
241
|
-
}
|
|
242
|
-
],
|
|
243
|
-
endpoint: 'https://dashscope.aliyuncs.com/compatible-mode/v1'
|
|
244
|
-
},
|
|
245
|
-
|
|
246
|
-
moonshot: {
|
|
247
|
-
id: 'moonshot',
|
|
248
|
-
name: 'MOONSHOT (KIMI)',
|
|
249
|
-
description: '200K context window',
|
|
250
|
-
category: 'direct',
|
|
251
|
-
models: [],
|
|
252
|
-
defaultModel: null,
|
|
253
|
-
options: [
|
|
254
|
-
{
|
|
255
|
-
id: 'api_key',
|
|
256
|
-
label: 'API KEY',
|
|
257
|
-
description: ['Get key at platform.moonshot.cn', 'Up to 200K context', 'Good for long documents'],
|
|
258
|
-
fields: ['apiKey'],
|
|
259
|
-
url: 'https://platform.moonshot.cn/console/api-keys'
|
|
260
|
-
}
|
|
261
|
-
],
|
|
262
|
-
endpoint: 'https://api.moonshot.cn/v1'
|
|
263
|
-
},
|
|
264
|
-
|
|
265
|
-
yi: {
|
|
266
|
-
id: 'yi',
|
|
267
|
-
name: '01.AI (YI)',
|
|
268
|
-
description: 'Yi models by Kai-Fu Lee',
|
|
269
|
-
category: 'direct',
|
|
270
|
-
models: [],
|
|
271
|
-
defaultModel: null,
|
|
272
|
-
options: [
|
|
273
|
-
{
|
|
274
|
-
id: 'api_key',
|
|
275
|
-
label: 'API KEY',
|
|
276
|
-
description: ['Get key at platform.01.ai', 'Yi-Large: GPT-4 level', 'Affordable pricing'],
|
|
277
|
-
fields: ['apiKey'],
|
|
278
|
-
url: 'https://platform.01.ai'
|
|
279
|
-
}
|
|
280
|
-
],
|
|
281
|
-
endpoint: 'https://api.01.ai/v1'
|
|
282
|
-
},
|
|
283
|
-
|
|
284
|
-
zhipu: {
|
|
285
|
-
id: 'zhipu',
|
|
286
|
-
name: 'ZHIPU AI (GLM)',
|
|
287
|
-
description: 'ChatGLM models',
|
|
288
|
-
category: 'direct',
|
|
289
|
-
models: [],
|
|
290
|
-
defaultModel: null,
|
|
291
|
-
options: [
|
|
292
|
-
{
|
|
293
|
-
id: 'api_key',
|
|
294
|
-
label: 'API KEY',
|
|
295
|
-
description: ['Get key at open.bigmodel.cn', 'ChatGLM-4 models', 'Strong multilingual'],
|
|
296
|
-
fields: ['apiKey'],
|
|
297
|
-
url: 'https://open.bigmodel.cn/usercenter/apikeys'
|
|
298
|
-
}
|
|
299
|
-
],
|
|
300
|
-
endpoint: 'https://open.bigmodel.cn/api/paas/v4'
|
|
301
|
-
},
|
|
302
|
-
|
|
303
|
-
baichuan: {
|
|
304
|
-
id: 'baichuan',
|
|
305
|
-
name: 'BAICHUAN',
|
|
306
|
-
description: 'Multilingual AI model',
|
|
307
|
-
category: 'direct',
|
|
308
|
-
models: [],
|
|
309
|
-
defaultModel: null,
|
|
310
|
-
options: [
|
|
311
|
-
{
|
|
312
|
-
id: 'api_key',
|
|
313
|
-
label: 'API KEY',
|
|
314
|
-
description: ['Get key at platform.baichuan-ai.com', 'Strong multilingual support', 'Competitive pricing'],
|
|
315
|
-
fields: ['apiKey'],
|
|
316
|
-
url: 'https://platform.baichuan-ai.com/console/apikey'
|
|
317
|
-
}
|
|
318
|
-
],
|
|
319
|
-
endpoint: 'https://api.baichuan-ai.com/v1'
|
|
320
|
-
},
|
|
321
|
-
};
|
|
322
|
-
|
|
323
|
-
module.exports = { DIRECT_PROVIDERS };
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AI Providers Configuration
|
|
3
|
-
* Each provider has connection options (API Key, Plans, etc.)
|
|
4
|
-
*
|
|
5
|
-
* IMPORTANT: models arrays are empty - models MUST be fetched from real APIs
|
|
6
|
-
* No hardcoded model lists allowed (see RULES.md)
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
const { DIRECT_PROVIDERS } = require('./direct-providers');
|
|
10
|
-
const { UNIFIED_PROVIDERS, LOCAL_PROVIDERS, CUSTOM_PROVIDERS } = require('./other-providers');
|
|
11
|
-
|
|
12
|
-
// Combine all providers
|
|
13
|
-
const PROVIDERS = {
|
|
14
|
-
...UNIFIED_PROVIDERS,
|
|
15
|
-
...DIRECT_PROVIDERS,
|
|
16
|
-
...LOCAL_PROVIDERS,
|
|
17
|
-
...CUSTOM_PROVIDERS,
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Get all providers
|
|
22
|
-
*/
|
|
23
|
-
const getProviders = () => Object.values(PROVIDERS);
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Get providers by category
|
|
27
|
-
*/
|
|
28
|
-
const getProvidersByCategory = (category) => {
|
|
29
|
-
return Object.values(PROVIDERS).filter(p => p.category === category);
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Get provider by ID
|
|
34
|
-
*/
|
|
35
|
-
const getProvider = (id) => PROVIDERS[id] || null;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Get provider options
|
|
39
|
-
*/
|
|
40
|
-
const getProviderOptions = (id) => {
|
|
41
|
-
const provider = PROVIDERS[id];
|
|
42
|
-
return provider ? provider.options : [];
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Get categories
|
|
47
|
-
*/
|
|
48
|
-
const getCategories = () => [
|
|
49
|
-
{ id: 'unified', name: 'UNIFIED (RECOMMENDED)', description: '1 API key for multiple models' },
|
|
50
|
-
{ id: 'direct', name: 'DIRECT PROVIDERS', description: 'Connect directly to each provider' },
|
|
51
|
-
{ id: 'local', name: 'LOCAL (FREE)', description: 'Run models on your machine' },
|
|
52
|
-
{ id: 'custom', name: 'CUSTOM', description: 'Self-hosted solutions' }
|
|
53
|
-
];
|
|
54
|
-
|
|
55
|
-
module.exports = {
|
|
56
|
-
PROVIDERS,
|
|
57
|
-
getProviders,
|
|
58
|
-
getProvidersByCategory,
|
|
59
|
-
getProvider,
|
|
60
|
-
getProviderOptions,
|
|
61
|
-
getCategories
|
|
62
|
-
};
|