hedgequantx 2.9.22 → 2.9.24

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.22",
3
+ "version": "2.9.24",
4
4
  "description": "HedgeQuantX - Prop Futures Trading CLI",
5
5
  "main": "src/app.js",
6
6
  "bin": {
@@ -334,17 +334,22 @@ const drawConnectionTest = async (agents, boxWidth, clearWithBanner) => {
334
334
 
335
335
  const W = boxWidth - 2;
336
336
 
337
- // Show loading state with spinner
337
+ // Show loading state with spinner inside closed box
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
+
343
+ // Centered spinner text inside box
344
+ const spinnerText = 'Testing connections...';
345
+ const paddedText = centerText(spinnerText, W);
346
+ console.log(chalk.cyan('║') + chalk.yellow(paddedText) + chalk.cyan('║'));
342
347
  console.log(chalk.cyan('║') + ' '.repeat(W) + chalk.cyan('║'));
348
+ console.log(chalk.cyan('╚' + '═'.repeat(W) + '╝'));
343
349
 
344
- // Start spinner on the loading line
345
- const spinnerText = 'Testing connections... Please wait';
350
+ // Start spinner below the box
346
351
  const spinner = ora({
347
- text: spinnerText,
352
+ text: '',
348
353
  spinner: 'dots',
349
354
  color: 'yellow'
350
355
  }).start();
@@ -10,7 +10,7 @@
10
10
  */
11
11
 
12
12
  const cliproxy = require('../cliproxy');
13
- const https = require('https');
13
+ const { extractJSON } = require('./parser');
14
14
 
15
15
  /** Test prompt to verify agent understands directive format */
16
16
  const TEST_PROMPT = `You are being tested. Respond ONLY with this exact JSON, nothing else:
@@ -161,6 +161,7 @@ const testAgentConnection = async (agent) => {
161
161
 
162
162
  /**
163
163
  * Validate that response matches expected JSON format
164
+ * Uses extractJSON from parser.js to handle MiniMax <think> tags and other formats
164
165
  * @param {string} content - Response content from agent
165
166
  * @returns {Object} { valid, error }
166
167
  */
@@ -169,53 +170,40 @@ const validateResponseFormat = (content) => {
169
170
  return { valid: false, error: 'Empty response' };
170
171
  }
171
172
 
172
- try {
173
- // Try to extract JSON from response
174
- let json;
175
-
176
- // Direct parse
177
- try {
178
- json = JSON.parse(content.trim());
179
- } catch (e) {
180
- // Try to find JSON in response
181
- const match = content.match(/\{[\s\S]*\}/);
182
- if (match) {
183
- json = JSON.parse(match[0]);
184
- } else {
185
- return { valid: false, error: 'No JSON in response' };
186
- }
187
- }
188
-
189
- // Check required fields
190
- if (!json.decision) {
191
- return { valid: false, error: 'Missing "decision" field' };
192
- }
193
-
194
- if (json.confidence === undefined) {
195
- return { valid: false, error: 'Missing "confidence" field' };
196
- }
197
-
198
- if (!json.reason) {
199
- return { valid: false, error: 'Missing "reason" field' };
200
- }
201
-
202
- // Validate decision value
203
- const validDecisions = ['approve', 'reject', 'modify'];
204
- if (!validDecisions.includes(json.decision)) {
205
- return { valid: false, error: `Invalid decision: ${json.decision}` };
206
- }
207
-
208
- // Validate confidence is number 0-100
209
- const conf = Number(json.confidence);
210
- if (isNaN(conf) || conf < 0 || conf > 100) {
211
- return { valid: false, error: `Invalid confidence: ${json.confidence}` };
212
- }
213
-
214
- return { valid: true, error: null };
215
-
216
- } catch (error) {
217
- return { valid: false, error: `Parse error: ${error.message}` };
173
+ // Use robust JSON extraction from parser.js
174
+ // Handles: direct JSON, markdown code blocks, JSON with extra text (MiniMax <think> tags)
175
+ const json = extractJSON(content);
176
+
177
+ if (!json) {
178
+ return { valid: false, error: 'No valid JSON found in response' };
179
+ }
180
+
181
+ // Check required fields
182
+ if (!json.decision) {
183
+ return { valid: false, error: 'Missing "decision" field' };
184
+ }
185
+
186
+ if (json.confidence === undefined) {
187
+ return { valid: false, error: 'Missing "confidence" field' };
218
188
  }
189
+
190
+ if (!json.reason) {
191
+ return { valid: false, error: 'Missing "reason" field' };
192
+ }
193
+
194
+ // Validate decision value
195
+ const validDecisions = ['approve', 'reject', 'modify'];
196
+ if (!validDecisions.includes(json.decision)) {
197
+ return { valid: false, error: `Invalid decision: ${json.decision}` };
198
+ }
199
+
200
+ // Validate confidence is number 0-100
201
+ const conf = Number(json.confidence);
202
+ if (isNaN(conf) || conf < 0 || conf > 100) {
203
+ return { valid: false, error: `Invalid confidence: ${json.confidence}` };
204
+ }
205
+
206
+ return { valid: true, error: null };
219
207
  };
220
208
 
221
209
  /**
@@ -338,7 +326,13 @@ const formatPreflightResults = (results, boxWidth) => {
338
326
  lines.push(dottedLine('Format', chalk.green('✓ VALID'), 9));
339
327
  } else {
340
328
  lines.push(dottedLine('Connection', chalk.red('✗ FAILED'), 9));
341
- lines.push(chalk.red(` Error: ${agent.error}`));
329
+ // Truncate error message to fit in box
330
+ const maxErrorLen = W - 16; // Account for " Error: " prefix
331
+ let errorMsg = agent.error || 'Unknown error';
332
+ if (errorMsg.length > maxErrorLen) {
333
+ errorMsg = errorMsg.substring(0, maxErrorLen - 3) + '...';
334
+ }
335
+ lines.push(chalk.red(` Error: ${errorMsg}`));
342
336
  }
343
337
 
344
338
  lines.push('');