polydev-ai 1.0.1 → 1.2.0

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/mcp/manifest.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polydev-perspectives",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "Agentic workflow assistant - get diverse perspectives from multiple LLMs when stuck or need enhanced reasoning",
5
5
  "author": "Polydev AI",
6
6
  "license": "MIT",
@@ -3,7 +3,7 @@
3
3
  // Lightweight stdio wrapper with local CLI functionality and remote Polydev MCP server fallback
4
4
  const fs = require('fs');
5
5
  const path = require('path');
6
- const { CLIManager } = require('../lib/cliManager');
6
+ const CLIManager = require('../lib/cliManager').default;
7
7
 
8
8
  class StdioMCPWrapper {
9
9
  constructor() {
@@ -204,7 +204,7 @@ class StdioMCPWrapper {
204
204
  const providerId = args.provider_id; // Optional - detect specific provider
205
205
 
206
206
  // Force detection using CLI Manager (no remote API calls)
207
- const results = await this.cliManager.forceCliDetection(providerId);
207
+ const results = await this.cliManager.forceCliDetection(null, providerId);
208
208
 
209
209
  // Save status locally to file-based cache
210
210
  await this.saveLocalCliStatus(results);
@@ -241,13 +241,13 @@ class StdioMCPWrapper {
241
241
  if (providerId) {
242
242
  // Get specific provider status
243
243
  const status = await this.cliManager.getCliStatus(providerId);
244
- results = status;
244
+ results[providerId] = status;
245
245
  } else {
246
246
  // Get all providers status
247
- const providers = this.cliManager.getAvailableProviders();
247
+ const providers = this.cliManager.getProviders();
248
248
  for (const provider of providers) {
249
249
  const status = await this.cliManager.getCliStatus(provider.id);
250
- results[provider.id] = status[provider.id];
250
+ results[provider.id] = status;
251
251
  }
252
252
  }
253
253
 
@@ -271,10 +271,10 @@ class StdioMCPWrapper {
271
271
  }
272
272
 
273
273
  /**
274
- * Local CLI prompt sending with remote perspectives fallback/supplement
274
+ * Local CLI prompt sending
275
275
  */
276
276
  async localSendCliPrompt(args) {
277
- console.error(`[Stdio Wrapper] Local CLI prompt sending with perspectives`);
277
+ console.error(`[Stdio Wrapper] Local CLI prompt sending`);
278
278
 
279
279
  try {
280
280
  const { provider_id, prompt, mode = 'args', timeout_ms = 30000 } = args;
@@ -283,174 +283,40 @@ class StdioMCPWrapper {
283
283
  throw new Error('provider_id and prompt are required');
284
284
  }
285
285
 
286
- // Use shorter timeout for faster fallback (5 seconds instead of 30)
287
- const gracefulTimeout = Math.min(timeout_ms, 5000);
288
-
289
- // Start both operations concurrently for better performance
290
- const [localResult, perspectivesResult] = await Promise.allSettled([
291
- this.cliManager.sendCliPrompt(provider_id, prompt, mode, gracefulTimeout),
292
- this.callPerspectivesForCli(args, null)
293
- ]);
294
-
295
- // Process results
296
- const localResponse = localResult.status === 'fulfilled' ? localResult.value : {
297
- success: false,
298
- error: `CLI check failed: ${localResult.reason?.message || 'Unknown error'}`,
299
- latency_ms: gracefulTimeout,
300
- timestamp: new Date().toISOString()
301
- };
302
-
303
- const perspectivesResponse = perspectivesResult.status === 'fulfilled' ? perspectivesResult.value : {
304
- success: false,
305
- error: `Perspectives failed: ${perspectivesResult.reason?.message || 'Unknown error'}`,
306
- timestamp: new Date().toISOString()
307
- };
308
-
309
- // Record usage locally (file-based analytics) - non-blocking
310
- this.recordLocalUsage(provider_id, prompt, localResponse).catch(err => {
311
- console.error('[Stdio Wrapper] Usage recording failed (non-critical):', err.message);
312
- });
286
+ // Send prompt using CLI Manager (local execution)
287
+ const response = await this.cliManager.sendCliPrompt(
288
+ provider_id,
289
+ prompt,
290
+ mode,
291
+ timeout_ms
292
+ );
313
293
 
314
- // Combine results
315
- return this.combineCliAndPerspectives(localResponse, perspectivesResponse, args);
294
+ // Record usage locally (file-based analytics)
295
+ await this.recordLocalUsage(provider_id, prompt, response);
316
296
 
317
- } catch (error) {
318
- console.error('[Stdio Wrapper] Local CLI prompt error:', error);
319
297
  return {
320
- success: false,
321
- error: error.message,
298
+ success: response.success,
299
+ content: response.content,
300
+ error: response.error,
301
+ tokens_used: response.tokensUsed,
302
+ latency_ms: response.latencyMs,
303
+ provider: provider_id,
304
+ mode,
322
305
  timestamp: new Date().toISOString(),
323
306
  local_only: true
324
307
  };
325
- }
326
- }
327
308
 
328
- /**
329
- * Call remote perspectives for CLI prompts
330
- */
331
- async callPerspectivesForCli(args, localResult) {
332
- console.error(`[Stdio Wrapper] Calling remote perspectives for CLI prompt`);
333
-
334
- try {
335
- const perspectivesRequest = {
336
- jsonrpc: '2.0',
337
- method: 'tools/call',
338
- params: {
339
- name: 'get_perspectives',
340
- arguments: {
341
- prompt: args.prompt,
342
- user_token: this.userToken,
343
- // Let the remote server use user's configured preferences for models
344
- // Don't specify models to use dashboard defaults
345
- project_memory: 'none',
346
- temperature: 0.7,
347
- max_tokens: 2000
348
- }
349
- },
350
- id: `perspectives-${Date.now()}`
351
- };
352
-
353
- const remoteResponse = await this.forwardToRemoteServer(perspectivesRequest);
354
-
355
- if (remoteResponse.result && remoteResponse.result.content && remoteResponse.result.content[0]) {
356
- return {
357
- success: true,
358
- content: remoteResponse.result.content[0].text,
359
- timestamp: new Date().toISOString()
360
- };
361
- } else if (remoteResponse.error) {
362
- return {
363
- success: false,
364
- error: remoteResponse.error.message || 'Remote perspectives failed',
365
- timestamp: new Date().toISOString()
366
- };
367
- } else {
368
- return {
369
- success: false,
370
- error: 'Unexpected remote response format',
371
- timestamp: new Date().toISOString()
372
- };
373
- }
374
309
  } catch (error) {
375
- console.error('[Stdio Wrapper] Perspectives call error:', error);
310
+ console.error('[Stdio Wrapper] Local CLI prompt error:', error);
376
311
  return {
377
312
  success: false,
378
- error: `Perspectives request failed: ${error.message}`,
379
- timestamp: new Date().toISOString()
313
+ error: error.message,
314
+ timestamp: new Date().toISOString(),
315
+ local_only: true
380
316
  };
381
317
  }
382
318
  }
383
319
 
384
- /**
385
- * Combine local CLI and remote perspectives results
386
- */
387
- combineCliAndPerspectives(localResult, perspectivesResult, args) {
388
- const combinedResult = {
389
- success: true,
390
- timestamp: new Date().toISOString(),
391
- provider: args.provider_id,
392
- mode: args.mode,
393
- sections: {
394
- local: localResult,
395
- remote: perspectivesResult
396
- }
397
- };
398
-
399
- // Determine overall success and fallback status
400
- if (localResult.success && perspectivesResult.success) {
401
- combinedResult.content = this.formatCombinedResponse(localResult, perspectivesResult, false);
402
- combinedResult.tokens_used = localResult.tokens_used || 0;
403
- combinedResult.latency_ms = localResult.latency_ms || 0;
404
- } else if (!localResult.success && perspectivesResult.success) {
405
- // Fallback case
406
- combinedResult.content = this.formatCombinedResponse(localResult, perspectivesResult, true);
407
- combinedResult.fallback_used = true;
408
- combinedResult.tokens_used = 0; // No local tokens used
409
- } else if (localResult.success && !perspectivesResult.success) {
410
- // Local succeeded, remote failed
411
- combinedResult.content = this.formatCombinedResponse(localResult, perspectivesResult, false);
412
- combinedResult.tokens_used = localResult.tokens_used || 0;
413
- combinedResult.latency_ms = localResult.latency_ms || 0;
414
- } else {
415
- // Both failed
416
- combinedResult.success = false;
417
- combinedResult.error = `Local CLI failed: ${localResult.error}; Perspectives also failed: ${perspectivesResult.error}`;
418
- }
419
-
420
- return combinedResult;
421
- }
422
-
423
- /**
424
- * Format combined response text
425
- */
426
- formatCombinedResponse(localResult, perspectivesResult, isFallback) {
427
- let formatted = '';
428
-
429
- if (localResult.success) {
430
- // Local CLI succeeded
431
- formatted += `🟢 **Local CLI Response** (${localResult.provider} - ${localResult.mode} mode)\n\n`;
432
- formatted += `${localResult.content}\n\n`;
433
- formatted += `*Latency: ${localResult.latency_ms || 0}ms | Tokens: ${localResult.tokens_used || 0}*\n\n`;
434
- formatted += `---\n\n`;
435
- } else if (isFallback) {
436
- // Local CLI failed, using fallback
437
- formatted += `⚠️ **Local CLI unavailable**: ${localResult.error}\n`;
438
- formatted += `Using perspectives fallback.\n\n`;
439
- formatted += `---\n\n`;
440
- }
441
-
442
- if (perspectivesResult.success) {
443
- const title = isFallback ? '🧠 **Perspectives Fallback**' : '🧠 **Supplemental Multi-Model Perspectives**';
444
- formatted += `${title}\n\n`;
445
- formatted += `${perspectivesResult.content}\n\n`;
446
- } else if (!isFallback) {
447
- // Show remote error only if not in fallback mode
448
- formatted += `❌ **Perspectives request failed**: ${perspectivesResult.error}\n\n`;
449
- }
450
-
451
- return formatted.trim();
452
- }
453
-
454
320
  /**
455
321
  * Save CLI status to local file cache
456
322
  */
@@ -488,20 +354,10 @@ class StdioMCPWrapper {
488
354
  const polydevevDir = path.join(homeDir, '.polydev');
489
355
  const usageFile = path.join(polydevevDir, 'cli-usage.json');
490
356
 
491
- // Ensure directory exists
492
- if (!fs.existsSync(polydevevDir)) {
493
- fs.mkdirSync(polydevevDir, { recursive: true });
494
- }
495
-
496
357
  // Load existing usage data
497
358
  let usageData = [];
498
359
  if (fs.existsSync(usageFile)) {
499
- try {
500
- usageData = JSON.parse(fs.readFileSync(usageFile, 'utf8'));
501
- } catch (parseError) {
502
- console.error('[Stdio Wrapper] Failed to parse existing usage file, starting fresh:', parseError);
503
- usageData = [];
504
- }
360
+ usageData = JSON.parse(fs.readFileSync(usageFile, 'utf8'));
505
361
  }
506
362
 
507
363
  // Add new usage record
@@ -510,8 +366,8 @@ class StdioMCPWrapper {
510
366
  provider: providerId,
511
367
  prompt_length: prompt.length,
512
368
  success: response.success,
513
- latency_ms: response.latency_ms || response.latencyMs || 0,
514
- tokens_used: response.tokens_used || response.tokensUsed || 0
369
+ latency_ms: response.latencyMs,
370
+ tokens_used: response.tokensUsed || 0
515
371
  });
516
372
 
517
373
  // Keep only last 1000 records
@@ -523,8 +379,7 @@ class StdioMCPWrapper {
523
379
  console.error(`[Stdio Wrapper] Usage recorded locally`);
524
380
 
525
381
  } catch (error) {
526
- console.error('[Stdio Wrapper] Failed to record local usage (non-critical):', error.message);
527
- // Don't throw - this is non-critical functionality
382
+ console.error('[Stdio Wrapper] Failed to record local usage:', error);
528
383
  }
529
384
  }
530
385
 
@@ -536,13 +391,8 @@ class StdioMCPWrapper {
536
391
  return `❌ **CLI Error**\n\n${result.error}\n\n*Timestamp: ${result.timestamp}*`;
537
392
  }
538
393
 
539
- // Handle combined CLI + perspectives response
540
- if (result.sections) {
541
- return result.content;
542
- }
543
-
544
394
  if (result.content) {
545
- // Standard prompt response
395
+ // Prompt response
546
396
  return `✅ **CLI Response** (${result.provider || 'Unknown'} - ${result.mode || 'unknown'} mode)\n\n${result.content}\n\n*Latency: ${result.latency_ms || 0}ms | Tokens: ${result.tokens_used || 0} | ${result.timestamp}*`;
547
397
  } else {
548
398
  // Status/detection response
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polydev-ai",
3
- "version": "1.0.1",
3
+ "version": "1.2.0",
4
4
  "description": "Agentic workflow assistant with CLI integration - get diverse perspectives from multiple LLMs when stuck or need enhanced reasoning",
5
5
  "keywords": [
6
6
  "mcp",
@@ -59,7 +59,6 @@
59
59
  "lucide-react": "^0.542.0",
60
60
  "marked": "^16.2.1",
61
61
  "next": "15.0.0",
62
- "polydev-ai": "^1.0.0",
63
62
  "posthog-js": "^1.157.2",
64
63
  "react": "^18.3.1",
65
64
  "react-dom": "^18.3.1",