hedgequantx 2.9.24 → 2.9.26

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hedgequantx",
3
- "version": "2.9.24",
3
+ "version": "2.9.26",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -334,16 +334,25 @@ const drawConnectionTest = async (agents, boxWidth, clearWithBanner) => {
334
334
 
335
335
  const W = boxWidth - 2;
336
336
 
337
- // Show loading state with spinner inside closed box
337
+ // Show loading state with spinner inside closed box (centered vertically)
338
338
  clearWithBanner();
339
339
  console.log(chalk.cyan('╔' + '═'.repeat(W) + '╗'));
340
340
  console.log(chalk.cyan('║') + chalk.yellow.bold(centerText('AI AGENTS CONNECTION TEST', W)) + chalk.cyan('║'));
341
341
  console.log(chalk.cyan('╠' + '═'.repeat(W) + '╣'));
342
342
 
343
+ // Empty lines for vertical centering (top)
344
+ console.log(chalk.cyan('║') + ' '.repeat(W) + chalk.cyan('║'));
345
+ console.log(chalk.cyan('║') + ' '.repeat(W) + chalk.cyan('║'));
346
+ console.log(chalk.cyan('║') + ' '.repeat(W) + chalk.cyan('║'));
347
+
343
348
  // Centered spinner text inside box
344
349
  const spinnerText = 'Testing connections...';
345
350
  const paddedText = centerText(spinnerText, W);
346
351
  console.log(chalk.cyan('║') + chalk.yellow(paddedText) + chalk.cyan('║'));
352
+
353
+ // Empty lines for vertical centering (bottom)
354
+ console.log(chalk.cyan('║') + ' '.repeat(W) + chalk.cyan('║'));
355
+ console.log(chalk.cyan('║') + ' '.repeat(W) + chalk.cyan('║'));
347
356
  console.log(chalk.cyan('║') + ' '.repeat(W) + chalk.cyan('║'));
348
357
  console.log(chalk.cyan('╚' + '═'.repeat(W) + '╝'));
349
358
 
@@ -19,6 +19,7 @@ const DEFAULT_RESPONSE = {
19
19
 
20
20
  /**
21
21
  * Extract JSON from a string that may contain markdown or extra text
22
+ * Handles MiniMax <think> tags, markdown code blocks, etc.
22
23
  */
23
24
  const extractJSON = (text) => {
24
25
  if (!text || typeof text !== 'string') return null;
@@ -36,8 +37,36 @@ const extractJSON = (text) => {
36
37
  } catch (e) { /* continue */ }
37
38
  }
38
39
 
39
- // Try to find JSON object pattern
40
- const jsonMatch = text.match(/\{[\s\S]*"decision"[\s\S]*\}/);
40
+ // Remove <think>...</think> tags (MiniMax)
41
+ let cleaned = text.replace(/<think>[\s\S]*?<\/think>/gi, '').trim();
42
+
43
+ // Try to parse cleaned text
44
+ try {
45
+ return JSON.parse(cleaned);
46
+ } catch (e) { /* continue */ }
47
+
48
+ // Find first complete JSON object using bracket matching
49
+ const startIdx = cleaned.indexOf('{');
50
+ if (startIdx !== -1) {
51
+ let depth = 0;
52
+ let endIdx = -1;
53
+ for (let i = startIdx; i < cleaned.length; i++) {
54
+ if (cleaned[i] === '{') depth++;
55
+ if (cleaned[i] === '}') depth--;
56
+ if (depth === 0) {
57
+ endIdx = i;
58
+ break;
59
+ }
60
+ }
61
+ if (endIdx !== -1) {
62
+ try {
63
+ return JSON.parse(cleaned.substring(startIdx, endIdx + 1));
64
+ } catch (e) { /* continue */ }
65
+ }
66
+ }
67
+
68
+ // Last resort: try to find JSON object pattern with "decision"
69
+ const jsonMatch = cleaned.match(/\{[^{}]*"decision"[^{}]*\}/);
41
70
  if (jsonMatch) {
42
71
  try {
43
72
  return JSON.parse(jsonMatch[0]);