polydev-ai 1.9.2 → 1.9.4
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/lib/cliManager.js +7 -7
- package/mcp/stdio-wrapper.js +47 -13
- package/package.json +6 -2
package/lib/cliManager.js
CHANGED
|
@@ -429,16 +429,16 @@ This is a known issue with @google/gemini-cli@0.3.4 and older Node.js versions.`
|
|
|
429
429
|
}
|
|
430
430
|
|
|
431
431
|
async sendCliPrompt(providerId, prompt, mode = 'args', timeoutMs = null, model = null) {
|
|
432
|
-
// Set default timeout for CLI
|
|
433
|
-
//
|
|
432
|
+
// Set default timeout for CLI responses (240 seconds / 4 minutes)
|
|
433
|
+
// CLI-within-CLI scenarios (Claude Code calling Claude Code) need generous timeouts
|
|
434
434
|
if (timeoutMs === null) {
|
|
435
|
-
timeoutMs =
|
|
435
|
+
timeoutMs = 240000; // 240 seconds (4 minutes) default for CLI responses
|
|
436
436
|
}
|
|
437
437
|
|
|
438
438
|
// Ensure timeoutMs is valid (not undefined, null, Infinity, or negative)
|
|
439
439
|
// Allow up to 600 seconds (10 minutes) for very complex operations
|
|
440
440
|
if (!timeoutMs || timeoutMs === Infinity || timeoutMs < 1 || timeoutMs > 600000) {
|
|
441
|
-
timeoutMs =
|
|
441
|
+
timeoutMs = 240000 // Default to 240 seconds (4 minutes) for CLI responses
|
|
442
442
|
}
|
|
443
443
|
|
|
444
444
|
const startTime = Date.now();
|
|
@@ -777,11 +777,11 @@ This is a known issue with @google/gemini-cli@0.3.4 and older Node.js versions.`
|
|
|
777
777
|
}
|
|
778
778
|
}
|
|
779
779
|
|
|
780
|
-
async executeCliCommand(command, args, mode = 'args', timeoutMs =
|
|
780
|
+
async executeCliCommand(command, args, mode = 'args', timeoutMs = 240000, stdinInput) {
|
|
781
781
|
// Ensure timeoutMs is valid (not undefined, null, Infinity, or negative)
|
|
782
|
-
//
|
|
782
|
+
// 240 seconds (4 minutes) default for CLI responses
|
|
783
783
|
if (!timeoutMs || timeoutMs === Infinity || timeoutMs < 1 || timeoutMs > 600000) {
|
|
784
|
-
timeoutMs =
|
|
784
|
+
timeoutMs = 240000 // Default to 240 seconds (4 minutes)
|
|
785
785
|
}
|
|
786
786
|
|
|
787
787
|
return new Promise((resolve, reject) => {
|
package/mcp/stdio-wrapper.js
CHANGED
|
@@ -35,7 +35,7 @@ if (typeof globalThis.fetch === 'undefined') {
|
|
|
35
35
|
});
|
|
36
36
|
|
|
37
37
|
req.on('error', reject);
|
|
38
|
-
req.setTimeout(
|
|
38
|
+
req.setTimeout(240000, () => { req.destroy(); reject(new Error('Request timed out')); });
|
|
39
39
|
if (options.body) req.write(options.body);
|
|
40
40
|
req.end();
|
|
41
41
|
});
|
|
@@ -436,8 +436,8 @@ Token will be saved automatically after login.`
|
|
|
436
436
|
return await this.handleGetPerspectivesWithCLIs(params, id);
|
|
437
437
|
}
|
|
438
438
|
|
|
439
|
-
// Handle
|
|
440
|
-
if (
|
|
439
|
+
// Handle CLI tools locally (support both prefixed and unprefixed names)
|
|
440
|
+
if (this.isCliTool(toolName)) {
|
|
441
441
|
return await this.handleLocalCliTool(request);
|
|
442
442
|
} else {
|
|
443
443
|
// Forward non-CLI tools to remote server
|
|
@@ -1170,6 +1170,10 @@ Error: ${error.message}`
|
|
|
1170
1170
|
console.error(`[Stdio Wrapper] Forwarding request to remote server`);
|
|
1171
1171
|
|
|
1172
1172
|
try {
|
|
1173
|
+
// Use AbortController for timeout if available, otherwise rely on fetch timeout
|
|
1174
|
+
const controller = typeof AbortController !== 'undefined' ? new AbortController() : null;
|
|
1175
|
+
const timeoutId = controller ? setTimeout(() => controller.abort(), 240000) : null; // 240s timeout
|
|
1176
|
+
|
|
1173
1177
|
const response = await fetch('https://www.polydev.ai/api/mcp', {
|
|
1174
1178
|
method: 'POST',
|
|
1175
1179
|
headers: {
|
|
@@ -1177,9 +1181,12 @@ Error: ${error.message}`
|
|
|
1177
1181
|
'Authorization': `Bearer ${this.userToken}`,
|
|
1178
1182
|
'User-Agent': 'polydev-stdio-wrapper/1.0.0'
|
|
1179
1183
|
},
|
|
1180
|
-
body: JSON.stringify(request)
|
|
1184
|
+
body: JSON.stringify(request),
|
|
1185
|
+
...(controller ? { signal: controller.signal } : {})
|
|
1181
1186
|
});
|
|
1182
1187
|
|
|
1188
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
1189
|
+
|
|
1183
1190
|
if (!response.ok) {
|
|
1184
1191
|
const errorText = await response.text();
|
|
1185
1192
|
console.error(`[Stdio Wrapper] Remote server error: ${response.status} - ${errorText}`);
|
|
@@ -1215,6 +1222,9 @@ Error: ${error.message}`
|
|
|
1215
1222
|
*/
|
|
1216
1223
|
isCliTool(toolName) {
|
|
1217
1224
|
const cliTools = [
|
|
1225
|
+
'force_cli_detection',
|
|
1226
|
+
'get_cli_status',
|
|
1227
|
+
'send_cli_prompt',
|
|
1218
1228
|
'polydev.force_cli_detection',
|
|
1219
1229
|
'polydev.get_cli_status',
|
|
1220
1230
|
'polydev.send_cli_prompt'
|
|
@@ -1274,14 +1284,17 @@ Error: ${error.message}`
|
|
|
1274
1284
|
let result;
|
|
1275
1285
|
|
|
1276
1286
|
switch (toolName) {
|
|
1287
|
+
case 'force_cli_detection':
|
|
1277
1288
|
case 'polydev.force_cli_detection':
|
|
1278
1289
|
result = await this.localForceCliDetection(args);
|
|
1279
1290
|
break;
|
|
1280
1291
|
|
|
1292
|
+
case 'get_cli_status':
|
|
1281
1293
|
case 'polydev.get_cli_status':
|
|
1282
1294
|
result = await this.localGetCliStatus(args);
|
|
1283
1295
|
break;
|
|
1284
1296
|
|
|
1297
|
+
case 'send_cli_prompt':
|
|
1285
1298
|
case 'polydev.send_cli_prompt':
|
|
1286
1299
|
result = await this.localSendCliPrompt(args);
|
|
1287
1300
|
break;
|
|
@@ -1551,7 +1564,23 @@ Error: ${error.message}`
|
|
|
1551
1564
|
if (model) {
|
|
1552
1565
|
console.error(`[Stdio Wrapper] Using model for ${providerEntry.cliId}: ${model}`);
|
|
1553
1566
|
}
|
|
1554
|
-
|
|
1567
|
+
let result = await this.cliManager.sendCliPrompt(providerEntry.cliId, prompt, mode, gracefulTimeout, model);
|
|
1568
|
+
|
|
1569
|
+
// If CLI failed with a model and the error suggests model issue, retry with CLI default
|
|
1570
|
+
if (!result.success && model) {
|
|
1571
|
+
const errorLower = (result.error || '').toLowerCase();
|
|
1572
|
+
const isModelError = errorLower.includes('not found') ||
|
|
1573
|
+
errorLower.includes('not supported') ||
|
|
1574
|
+
errorLower.includes('invalid model') ||
|
|
1575
|
+
errorLower.includes('entity was not found') ||
|
|
1576
|
+
errorLower.includes('does not exist') ||
|
|
1577
|
+
errorLower.includes('unknown model');
|
|
1578
|
+
if (isModelError) {
|
|
1579
|
+
console.error(`[Stdio Wrapper] Model '${model}' failed for ${providerEntry.cliId}, retrying with CLI default...`);
|
|
1580
|
+
result = await this.cliManager.sendCliPrompt(providerEntry.cliId, prompt, mode, gracefulTimeout, null);
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1555
1584
|
return {
|
|
1556
1585
|
provider_id: providerEntry.cliId,
|
|
1557
1586
|
original_provider: providerEntry.provider,
|
|
@@ -1657,18 +1686,23 @@ Error: ${error.message}`
|
|
|
1657
1686
|
console.error('[Polydev] CLI detection ready, proceeding with request');
|
|
1658
1687
|
}
|
|
1659
1688
|
|
|
1660
|
-
|
|
1661
|
-
|
|
1689
|
+
// Use cached status (refreshed by smart scheduler) instead of forceCliDetection on every request
|
|
1690
|
+
const results = await this.cliManager.getCliStatus();
|
|
1691
|
+
console.error(`[Stdio Wrapper] CLI status (cached):`, JSON.stringify(results, null, 2));
|
|
1662
1692
|
const availableProviders = [];
|
|
1663
1693
|
const unavailableProviders = [];
|
|
1664
1694
|
|
|
1665
|
-
//
|
|
1666
|
-
//
|
|
1667
|
-
//
|
|
1668
|
-
|
|
1695
|
+
// ALWAYS check ALL CLIs (they're FREE) — don't limit to userProviderOrder
|
|
1696
|
+
// userProviderOrder only affects ordering, not which CLIs get checked
|
|
1697
|
+
// This fixes the bug where CLIs were missed because model-preferences API
|
|
1698
|
+
// only returned providerOrder for credits-tier models
|
|
1699
|
+
const allCliIds = ['claude_code', 'codex_cli', 'gemini_cli'];
|
|
1700
|
+
const userOrder = (this.userProviderOrder && this.userProviderOrder.length > 0)
|
|
1669
1701
|
? this.userProviderOrder
|
|
1670
|
-
: [
|
|
1671
|
-
|
|
1702
|
+
: [];
|
|
1703
|
+
// Merge: user's preferred order first, then any CLIs not in their order
|
|
1704
|
+
const priorityOrder = [...new Set([...userOrder, ...allCliIds])];
|
|
1705
|
+
console.error(`[Stdio Wrapper] Using provider order: ${priorityOrder.join(' > ')} (user order: ${userOrder.join(', ') || 'none'})`);
|
|
1672
1706
|
|
|
1673
1707
|
for (const providerId of priorityOrder) {
|
|
1674
1708
|
const status = results[providerId];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "polydev-ai",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.4",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=20.x <=22.x"
|
|
6
6
|
},
|
|
@@ -45,7 +45,11 @@
|
|
|
45
45
|
"test:admin": "jest __tests__/api/admin",
|
|
46
46
|
"mcp": "node mcp/server.js",
|
|
47
47
|
"mcp-stdio": "node mcp/stdio-wrapper.js",
|
|
48
|
-
"cli-detect": "node -e \"const CLIManager = require('./lib/cliManager').default; const m = new CLIManager(); m.forceCliDetection().then(console.log);\""
|
|
48
|
+
"cli-detect": "node -e \"const CLIManager = require('./lib/cliManager').default; const m = new CLIManager(); m.forceCliDetection().then(console.log);\"",
|
|
49
|
+
"release": "bash scripts/release.sh",
|
|
50
|
+
"release:patch": "bash scripts/release.sh patch",
|
|
51
|
+
"release:minor": "bash scripts/release.sh minor",
|
|
52
|
+
"release:major": "bash scripts/release.sh major"
|
|
49
53
|
},
|
|
50
54
|
"repository": {
|
|
51
55
|
"type": "git",
|