hedgequantx 2.7.70 → 2.7.72
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/package.json +1 -1
- package/src/menus/dashboard.js +4 -18
- package/src/pages/ai-agents-ui.js +58 -3
- package/src/pages/ai-agents.js +22 -6
package/package.json
CHANGED
package/src/menus/dashboard.js
CHANGED
|
@@ -242,24 +242,10 @@ const handleUpdate = async () => {
|
|
|
242
242
|
|
|
243
243
|
spinner.succeed(`UPDATED TO V${latestVersion}!`);
|
|
244
244
|
console.log(chalk.green('\n ✓ UPDATE SUCCESSFUL!'));
|
|
245
|
-
console.log(chalk.
|
|
246
|
-
|
|
247
|
-
await
|
|
248
|
-
|
|
249
|
-
// Restart HQX
|
|
250
|
-
try {
|
|
251
|
-
const child = spawn('hqx', [], {
|
|
252
|
-
stdio: 'inherit',
|
|
253
|
-
detached: true,
|
|
254
|
-
shell: true
|
|
255
|
-
});
|
|
256
|
-
child.unref();
|
|
257
|
-
process.exit(0);
|
|
258
|
-
} catch (e) {
|
|
259
|
-
console.log(chalk.yellow('\n PLEASE RESTART HQX MANUALLY:'));
|
|
260
|
-
console.log(chalk.white(' hqx'));
|
|
261
|
-
await prompts.waitForEnter();
|
|
262
|
-
}
|
|
245
|
+
console.log(chalk.yellow('\n PLEASE RESTART HQX TO USE THE NEW VERSION:'));
|
|
246
|
+
console.log(chalk.white(' hqx'));
|
|
247
|
+
await prompts.waitForEnter();
|
|
248
|
+
process.exit(0);
|
|
263
249
|
|
|
264
250
|
} catch (error) {
|
|
265
251
|
if (spinner) spinner.fail('UPDATE ERROR');
|
|
@@ -155,15 +155,70 @@ const drawProvidersTable = (providers, config, boxWidth) => {
|
|
|
155
155
|
};
|
|
156
156
|
|
|
157
157
|
/**
|
|
158
|
-
* Draw models table
|
|
158
|
+
* Draw models table with 2-column layout
|
|
159
159
|
* @param {Object} provider - Provider object
|
|
160
160
|
* @param {Array} models - List of models
|
|
161
161
|
* @param {number} boxWidth - Box width
|
|
162
162
|
*/
|
|
163
163
|
const drawModelsTable = (provider, models, boxWidth) => {
|
|
164
164
|
const W = boxWidth - 2;
|
|
165
|
-
const
|
|
166
|
-
|
|
165
|
+
const colWidth = Math.floor(W / 2);
|
|
166
|
+
|
|
167
|
+
// New rectangle
|
|
168
|
+
console.log(chalk.cyan('╔' + '═'.repeat(W) + '╗'));
|
|
169
|
+
console.log(chalk.cyan('║') + chalk[provider.color].bold(centerText(`${provider.name.toUpperCase()} - SELECT MODEL`, W)) + chalk.cyan('║'));
|
|
170
|
+
console.log(chalk.cyan('╠' + '═'.repeat(W) + '╣'));
|
|
171
|
+
|
|
172
|
+
// Calculate rows (2 columns)
|
|
173
|
+
const rows = Math.ceil(models.length / 2);
|
|
174
|
+
|
|
175
|
+
// Find max model name length for alignment
|
|
176
|
+
const maxNameLen = Math.min(
|
|
177
|
+
Math.max(...models.map(m => m.name.length)),
|
|
178
|
+
colWidth - 8 // [XX] + space + padding
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
for (let row = 0; row < rows; row++) {
|
|
182
|
+
const leftIdx = row;
|
|
183
|
+
const rightIdx = row + rows;
|
|
184
|
+
const leftModel = models[leftIdx];
|
|
185
|
+
const rightModel = models[rightIdx];
|
|
186
|
+
|
|
187
|
+
// Left column
|
|
188
|
+
let leftCol = '';
|
|
189
|
+
if (leftModel) {
|
|
190
|
+
const num = String(leftIdx + 1).padStart(2);
|
|
191
|
+
const name = leftModel.name.length > maxNameLen
|
|
192
|
+
? leftModel.name.substring(0, maxNameLen - 2) + '..'
|
|
193
|
+
: leftModel.name.padEnd(maxNameLen);
|
|
194
|
+
leftCol = ` ${chalk.cyan(`[${num}]`)} ${chalk.white(name)}`;
|
|
195
|
+
const leftLen = 2 + 4 + 1 + maxNameLen; // padding + [XX] + space + name
|
|
196
|
+
leftCol += ' '.repeat(Math.max(0, colWidth - leftLen));
|
|
197
|
+
} else {
|
|
198
|
+
leftCol = ' '.repeat(colWidth);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Right column
|
|
202
|
+
let rightCol = '';
|
|
203
|
+
const rightColWidth = W - colWidth;
|
|
204
|
+
if (rightModel) {
|
|
205
|
+
const num = String(rightIdx + 1).padStart(2);
|
|
206
|
+
const name = rightModel.name.length > maxNameLen
|
|
207
|
+
? rightModel.name.substring(0, maxNameLen - 2) + '..'
|
|
208
|
+
: rightModel.name.padEnd(maxNameLen);
|
|
209
|
+
rightCol = ` ${chalk.cyan(`[${num}]`)} ${chalk.white(name)}`;
|
|
210
|
+
const rightLen = 2 + 4 + 1 + maxNameLen;
|
|
211
|
+
rightCol += ' '.repeat(Math.max(0, rightColWidth - rightLen));
|
|
212
|
+
} else {
|
|
213
|
+
rightCol = ' '.repeat(rightColWidth);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
console.log(chalk.cyan('║') + leftCol + rightCol + chalk.cyan('║'));
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
console.log(chalk.cyan('╠' + '─'.repeat(W) + '╣'));
|
|
220
|
+
console.log(chalk.cyan('║') + chalk.red(centerText('[B] BACK', W)) + chalk.cyan('║'));
|
|
221
|
+
console.log(chalk.cyan('╚' + '═'.repeat(W) + '╝'));
|
|
167
222
|
};
|
|
168
223
|
|
|
169
224
|
/**
|
package/src/pages/ai-agents.js
CHANGED
|
@@ -219,6 +219,24 @@ const handleCliProxyConnection = async (provider, config, boxWidth) => {
|
|
|
219
219
|
return false;
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
+
spinner.text = 'EXCHANGING TOKEN...';
|
|
223
|
+
|
|
224
|
+
// Wait for login process to exit naturally (it saves auth file then exits)
|
|
225
|
+
await new Promise((resolve) => {
|
|
226
|
+
if (!loginResult.childProcess) return resolve();
|
|
227
|
+
|
|
228
|
+
const timeout = setTimeout(() => {
|
|
229
|
+
// Safety timeout after 15s - kill if still running
|
|
230
|
+
try { loginResult.childProcess.kill(); } catch (e) { /* ignore */ }
|
|
231
|
+
resolve();
|
|
232
|
+
}, 15000);
|
|
233
|
+
|
|
234
|
+
loginResult.childProcess.on('exit', () => {
|
|
235
|
+
clearTimeout(timeout);
|
|
236
|
+
resolve();
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
|
|
222
240
|
spinner.succeed('AUTHENTICATION SUCCESSFUL!');
|
|
223
241
|
} catch (err) {
|
|
224
242
|
spinner.fail(`ERROR: ${err.message}`);
|
|
@@ -232,13 +250,11 @@ const handleCliProxyConnection = async (provider, config, boxWidth) => {
|
|
|
232
250
|
await prompts.waitForEnter();
|
|
233
251
|
}
|
|
234
252
|
|
|
235
|
-
//
|
|
236
|
-
if (loginResult.childProcess) {
|
|
237
|
-
try { loginResult.childProcess.kill(); } catch (e) { /* ignore */ }
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
// Fetch models directly from CLIProxy API (models are already available)
|
|
253
|
+
// Small delay for CLIProxy to detect new auth file
|
|
241
254
|
const spinner = ora({ text: 'LOADING MODELS...', color: 'yellow' }).start();
|
|
255
|
+
await new Promise(r => setTimeout(r, 1000));
|
|
256
|
+
|
|
257
|
+
// Fetch models from CLIProxy API
|
|
242
258
|
const modelsResult = await cliproxy.fetchProviderModels(provider.id);
|
|
243
259
|
spinner.stop();
|
|
244
260
|
|