mcp-prompt-optimizer 1.4.2 → 2.2.3
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/CHANGELOG.md +78 -53
- package/CROSS-PLATFORM.md +3 -3
- package/README.md +99 -39
- package/index.js +843 -187
- package/lib/api-key-manager.js +191 -138
- package/lib/check-status.js +1 -1
- package/package.json +80 -5
- package/tests/README.md +0 -232
- package/tests/comprehensive-test.js +0 -692
- package/tests/integration-test.js +0 -446
- package/tests/minimal-test.js +0 -265
- package/tests/quick-test.js +0 -256
- package/tests/simple-test.js +0 -171
- package/tests/test-runner.js +0 -322
package/lib/api-key-manager.js
CHANGED
|
@@ -15,7 +15,7 @@ const packageJson = require('../package.json');
|
|
|
15
15
|
class CloudApiKeyManager {
|
|
16
16
|
constructor(apiKey, options = {}) {
|
|
17
17
|
this.apiKey = apiKey;
|
|
18
|
-
this.backendUrl = options.backendUrl || process.env.OPTIMIZER_BACKEND_URL || 'https://p01--project-optimizer--
|
|
18
|
+
this.backendUrl = options.backendUrl || process.env.OPTIMIZER_BACKEND_URL || 'https://p01--project-optimizer--fvmrdk8m9k9j.code.run';
|
|
19
19
|
this.cacheFile = path.join(os.homedir(), '.mcp-cloud-api-cache.json');
|
|
20
20
|
this.healthFile = path.join(os.homedir(), '.mcp-cloud-health.json');
|
|
21
21
|
this.cacheExpiry = options.cacheExpiry || 24 * 60 * 60 * 1000; // 24 hours
|
|
@@ -196,8 +196,7 @@ class CloudApiKeyManager {
|
|
|
196
196
|
|
|
197
197
|
this.log(`API key format valid: ${formatCheck.keyType}`);
|
|
198
198
|
|
|
199
|
-
|
|
200
|
-
if (this.developmentMode || formatCheck.keyType === 'development' || formatCheck.keyType === 'testing') {
|
|
199
|
+
if (this.developmentMode || formatCheck.keyType === 'testing') {
|
|
201
200
|
this.log('Development/testing mode detected, using mock validation', 'warn');
|
|
202
201
|
const mockValidation = this.generateMockValidation(formatCheck.keyType);
|
|
203
202
|
await this.cacheValidation(mockValidation);
|
|
@@ -290,99 +289,23 @@ class CloudApiKeyManager {
|
|
|
290
289
|
|
|
291
290
|
// ✅ FIXED: Correct API endpoint URL
|
|
292
291
|
async validateWithBackend() {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
},
|
|
305
|
-
timeout: this.requestTimeout
|
|
306
|
-
};
|
|
307
|
-
|
|
308
|
-
this.log(`Making request to: ${url}`);
|
|
309
|
-
this.log(`Using API key: ${this.apiKey.substring(0, 16)}...`);
|
|
310
|
-
|
|
311
|
-
const client = this.backendUrl.startsWith('https://') ? https : http;
|
|
312
|
-
const req = client.request(url, options, (res) => {
|
|
313
|
-
let data = '';
|
|
314
|
-
|
|
315
|
-
res.on('data', (chunk) => {
|
|
316
|
-
data += chunk;
|
|
317
|
-
});
|
|
318
|
-
|
|
319
|
-
res.on('end', () => {
|
|
320
|
-
this.log(`Response status: ${res.statusCode}`);
|
|
321
|
-
|
|
322
|
-
try {
|
|
323
|
-
if (res.statusCode === 200) {
|
|
324
|
-
const validation = JSON.parse(data);
|
|
325
|
-
this.log(`Validation successful: ${JSON.stringify(validation, null, 2)}`);
|
|
326
|
-
resolve(validation);
|
|
327
|
-
} else if (res.statusCode === 401) {
|
|
328
|
-
reject(new Error('Invalid API key or unauthorized access'));
|
|
329
|
-
} else if (res.statusCode === 403) {
|
|
330
|
-
reject(new Error('API key expired or quota exceeded'));
|
|
331
|
-
} else if (res.statusCode === 429) {
|
|
332
|
-
reject(new Error('Rate limit exceeded. Please try again later.'));
|
|
333
|
-
} else if (res.statusCode === 500) {
|
|
334
|
-
reject(new Error('Backend server error. Please try again later.'));
|
|
335
|
-
} else if (res.statusCode === 503) {
|
|
336
|
-
reject(new Error('Backend service temporarily unavailable. Please try again later.'));
|
|
337
|
-
} else {
|
|
338
|
-
let errorMessage;
|
|
339
|
-
try {
|
|
340
|
-
const error = JSON.parse(data);
|
|
341
|
-
errorMessage = error.detail || error.message || `HTTP ${res.statusCode}`;
|
|
342
|
-
} catch {
|
|
343
|
-
errorMessage = `HTTP ${res.statusCode}: ${data}`;
|
|
344
|
-
}
|
|
345
|
-
reject(new Error(errorMessage));
|
|
346
|
-
}
|
|
347
|
-
} catch (parseError) {
|
|
348
|
-
this.log(`Parse error: ${parseError.message}`, 'error');
|
|
349
|
-
this.log(`Raw response: ${data}`, 'error');
|
|
350
|
-
reject(new Error(`Invalid response format: ${parseError.message}`));
|
|
351
|
-
}
|
|
352
|
-
});
|
|
353
|
-
});
|
|
354
|
-
|
|
355
|
-
req.on('error', (error) => {
|
|
356
|
-
this.log(`Network error: ${error.message}`, 'error');
|
|
357
|
-
|
|
358
|
-
// Enhanced error classification
|
|
359
|
-
if (error.code === 'ENOTFOUND') {
|
|
360
|
-
reject(new Error(`DNS resolution failed: Cannot resolve ${this.backendUrl.replace(/^https?:\/\//, '')}`));
|
|
361
|
-
} else if (error.code === 'ECONNREFUSED') {
|
|
362
|
-
reject(new Error(`Connection refused: Backend server may be down`));
|
|
363
|
-
} else if (error.code === 'ETIMEDOUT') {
|
|
364
|
-
reject(new Error(`Connection timeout: Backend server is not responding`));
|
|
365
|
-
} else if (error.code === 'ECONNRESET') {
|
|
366
|
-
reject(new Error(`Connection reset: Network instability detected`));
|
|
367
|
-
} else {
|
|
368
|
-
reject(new Error(`Network error: ${error.message}`));
|
|
369
|
-
}
|
|
370
|
-
});
|
|
371
|
-
|
|
372
|
-
req.on('timeout', () => {
|
|
373
|
-
req.destroy();
|
|
374
|
-
reject(new Error('Request timeout - backend may be unavailable'));
|
|
375
|
-
});
|
|
376
|
-
|
|
377
|
-
req.setTimeout(this.requestTimeout);
|
|
378
|
-
req.end();
|
|
379
|
-
});
|
|
292
|
+
const endpoint = '/api/v1/api-keys/validate';
|
|
293
|
+
const method = 'POST';
|
|
294
|
+
|
|
295
|
+
try {
|
|
296
|
+
const validation = await this._makeBackendRequest(endpoint, null, method);
|
|
297
|
+
this.log(`Validation successful: ${JSON.stringify(validation, null, 2)}`);
|
|
298
|
+
return validation;
|
|
299
|
+
} catch (error) {
|
|
300
|
+
this.log(`Backend validation request failed: ${error.message}`, 'error');
|
|
301
|
+
throw error;
|
|
302
|
+
}
|
|
380
303
|
}
|
|
381
304
|
|
|
382
305
|
// ✅ FIXED: Correct API endpoint URL
|
|
383
306
|
async getQuotaStatus() {
|
|
384
307
|
try {
|
|
385
|
-
const url = `${this.backendUrl}/api/v1/
|
|
308
|
+
const url = `${this.backendUrl}/api/v1/api-keys/quota-status`;
|
|
386
309
|
|
|
387
310
|
const options = {
|
|
388
311
|
method: 'GET',
|
|
@@ -462,38 +385,7 @@ class CloudApiKeyManager {
|
|
|
462
385
|
}
|
|
463
386
|
}
|
|
464
387
|
|
|
465
|
-
// Enhanced quota status checking
|
|
466
|
-
async checkQuotaStatus(validation) {
|
|
467
|
-
const quota = validation.quota || {};
|
|
468
|
-
|
|
469
|
-
if (quota.unlimited) {
|
|
470
|
-
return { allowed: true, unlimited: true };
|
|
471
|
-
}
|
|
472
388
|
|
|
473
|
-
const quotaUsed = quota.used || 0;
|
|
474
|
-
const quotaLimit = quota.limit || 5000;
|
|
475
|
-
const quotaRemaining = quota.remaining || (quotaLimit - quotaUsed);
|
|
476
|
-
|
|
477
|
-
if (quotaUsed >= quotaLimit) {
|
|
478
|
-
const tier = validation.tier || 'explorer';
|
|
479
|
-
const upgradeMessage = tier === 'explorer'
|
|
480
|
-
? 'Upgrade to Creator ($25.99/mo) for 18,000 optimizations: https://promptoptimizer-blog.vercel.app/pricing'
|
|
481
|
-
: 'Quota will reset on your next billing cycle.';
|
|
482
|
-
|
|
483
|
-
throw new Error(
|
|
484
|
-
`Monthly quota exceeded (${quotaUsed}/${quotaLimit}). ${upgradeMessage}`
|
|
485
|
-
);
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
return {
|
|
489
|
-
allowed: true,
|
|
490
|
-
unlimited: false,
|
|
491
|
-
used: quotaUsed,
|
|
492
|
-
limit: quotaLimit,
|
|
493
|
-
remaining: quotaRemaining,
|
|
494
|
-
usage_percentage: (quotaUsed / quotaLimit) * 100
|
|
495
|
-
};
|
|
496
|
-
}
|
|
497
389
|
|
|
498
390
|
// Enhanced caching with metadata
|
|
499
391
|
async cacheValidation(validation) {
|
|
@@ -593,13 +485,10 @@ class CloudApiKeyManager {
|
|
|
593
485
|
// Step 1: Validate API key
|
|
594
486
|
const validation = await this.validateApiKey();
|
|
595
487
|
|
|
596
|
-
// Step 2:
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
} else {
|
|
601
|
-
quotaStatus = await this.checkQuotaStatus(validation);
|
|
602
|
-
}
|
|
488
|
+
// Step 2: Get comprehensive quota status
|
|
489
|
+
const info = await this.getApiKeyInfo();
|
|
490
|
+
let quotaStatus = info.quota;
|
|
491
|
+
validation = info; // Use info as the main validation object for consistency
|
|
603
492
|
|
|
604
493
|
// Step 3: Log success
|
|
605
494
|
const mode = validation.mock_mode ? '(mock)' :
|
|
@@ -633,24 +522,57 @@ class CloudApiKeyManager {
|
|
|
633
522
|
|
|
634
523
|
// Enhanced API key info with mode detection
|
|
635
524
|
async getApiKeyInfo() {
|
|
525
|
+
const formatCheck = this.validateApiKeyFormat(this.apiKey);
|
|
526
|
+
if (this.developmentMode || formatCheck.keyType === 'development' || formatCheck.keyType === 'testing') {
|
|
527
|
+
this.log('Development/testing mode detected for getApiKeyInfo, returning mock data.', 'warn');
|
|
528
|
+
return {
|
|
529
|
+
tier: 'testing',
|
|
530
|
+
features: {
|
|
531
|
+
optimization: true,
|
|
532
|
+
template_search: true,
|
|
533
|
+
template_auto_save: true,
|
|
534
|
+
optimization_insights: true,
|
|
535
|
+
bayesian_optimization: true,
|
|
536
|
+
agui_features: true
|
|
537
|
+
},
|
|
538
|
+
quota: {
|
|
539
|
+
unlimited: false,
|
|
540
|
+
used: Math.floor(Math.random() * 100),
|
|
541
|
+
limit: 1000,
|
|
542
|
+
remaining: 1000 - Math.floor(Math.random() * 100)
|
|
543
|
+
},
|
|
544
|
+
isValid: true,
|
|
545
|
+
keyType: formatCheck.keyType,
|
|
546
|
+
mode: {
|
|
547
|
+
mock: true,
|
|
548
|
+
fallback: false,
|
|
549
|
+
offline: false,
|
|
550
|
+
development: this.developmentMode
|
|
551
|
+
}
|
|
552
|
+
};
|
|
553
|
+
}
|
|
554
|
+
|
|
636
555
|
try {
|
|
637
|
-
|
|
638
|
-
const
|
|
556
|
+
// Directly call the new quota-status endpoint
|
|
557
|
+
const quotaStatusResponse = await this._makeBackendRequest('/api/v1/api-keys/quota-status', null, 'GET');
|
|
639
558
|
|
|
559
|
+
// The backend /mcp/quota-status endpoint returns a comprehensive object
|
|
560
|
+
// that includes tier, quota details, and features.
|
|
640
561
|
return {
|
|
641
|
-
tier:
|
|
642
|
-
features:
|
|
643
|
-
quota:
|
|
562
|
+
tier: quotaStatusResponse.tier,
|
|
563
|
+
features: quotaStatusResponse.features_available || {},
|
|
564
|
+
quota: quotaStatusResponse.quota,
|
|
644
565
|
isValid: true,
|
|
645
|
-
keyType:
|
|
566
|
+
keyType: quotaStatusResponse.account_type || this.validateApiKeyFormat(this.apiKey).keyType,
|
|
646
567
|
mode: {
|
|
647
|
-
mock:
|
|
648
|
-
fallback:
|
|
649
|
-
offline:
|
|
568
|
+
mock: false, // This endpoint doesn't return mock status
|
|
569
|
+
fallback: false,
|
|
570
|
+
offline: false,
|
|
650
571
|
development: this.developmentMode
|
|
651
572
|
}
|
|
652
573
|
};
|
|
653
574
|
} catch (error) {
|
|
575
|
+
this.log(`Error getting API key info: ${error.message}`, 'error');
|
|
654
576
|
return {
|
|
655
577
|
tier: null,
|
|
656
578
|
features: {},
|
|
@@ -692,6 +614,137 @@ class CloudApiKeyManager {
|
|
|
692
614
|
if (!this.apiKey) return 'No key';
|
|
693
615
|
return `${this.apiKey.substring(0, 8)}...${this.apiKey.slice(-4)}`;
|
|
694
616
|
}
|
|
617
|
+
|
|
618
|
+
async getDiagnosticInfo() {
|
|
619
|
+
const diagnosticInfo = {
|
|
620
|
+
apiKey: this.apiKey ? this.formatKeyForDisplay() : 'Not set',
|
|
621
|
+
backendUrl: this.backendUrl,
|
|
622
|
+
cacheFile: this.cacheFile,
|
|
623
|
+
healthFile: this.healthFile,
|
|
624
|
+
cacheExpiry: this.cacheExpiry,
|
|
625
|
+
fallbackCacheExpiry: this.fallbackCacheExpiry,
|
|
626
|
+
offlineMode: this.offlineMode,
|
|
627
|
+
developmentMode: this.developmentMode,
|
|
628
|
+
maxRetries: this.maxRetries,
|
|
629
|
+
requestTimeout: this.requestTimeout,
|
|
630
|
+
nodeEnv: process.env.NODE_ENV || 'not set',
|
|
631
|
+
packageVersion: packageJson.version,
|
|
632
|
+
networkHealth: { ...this.networkHealth },
|
|
633
|
+
cache: {},
|
|
634
|
+
keyFormat: this.validateApiKeyFormat(this.apiKey),
|
|
635
|
+
backendConnectivity: { status: 'unknown', error: null, responseTime: null }
|
|
636
|
+
};
|
|
637
|
+
|
|
638
|
+
// Get cache status
|
|
639
|
+
try {
|
|
640
|
+
const cached = await this.getCachedValidation();
|
|
641
|
+
if (cached) {
|
|
642
|
+
diagnosticInfo.cache.exists = true;
|
|
643
|
+
diagnosticInfo.cache.expired = this.isCacheExpired(cached);
|
|
644
|
+
diagnosticInfo.cache.fallbackExpired = this.isFallbackCacheExpired(cached);
|
|
645
|
+
diagnosticInfo.cache.age = Math.round((Date.now() - cached.timestamp) / 1000 / 60);
|
|
646
|
+
diagnosticInfo.cache.backendUrl = cached.backendUrl;
|
|
647
|
+
diagnosticInfo.cache.packageVersion = cached.packageVersion;
|
|
648
|
+
} else {
|
|
649
|
+
diagnosticInfo.cache.exists = false;
|
|
650
|
+
}
|
|
651
|
+
} catch (error) {
|
|
652
|
+
diagnosticInfo.cache.error = error.message;
|
|
653
|
+
diagnosticInfo.cache.exists = false;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
// Check backend connectivity
|
|
657
|
+
if (this.apiKey) { // Only check if API key is present
|
|
658
|
+
try {
|
|
659
|
+
const startTime = Date.now();
|
|
660
|
+
await this.validateWithBackend(); // This will attempt to connect to the backend
|
|
661
|
+
const responseTime = Date.now() - startTime;
|
|
662
|
+
diagnosticInfo.backendConnectivity.status = 'success';
|
|
663
|
+
diagnosticInfo.backendConnectivity.responseTime = responseTime;
|
|
664
|
+
} catch (error) {
|
|
665
|
+
diagnosticInfo.backendConnectivity.status = 'failed';
|
|
666
|
+
diagnosticInfo.backendConnectivity.error = error.message;
|
|
667
|
+
}
|
|
668
|
+
} else {
|
|
669
|
+
diagnosticInfo.backendConnectivity.status = 'skipped';
|
|
670
|
+
diagnosticInfo.backendConnectivity.error = 'No API key provided for connectivity check.';
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
return diagnosticInfo;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
async _makeBackendRequest(endpoint, data, method = 'POST') {
|
|
677
|
+
return new Promise((resolve, reject) => {
|
|
678
|
+
const url = `${this.backendUrl}${endpoint}`;
|
|
679
|
+
|
|
680
|
+
const options = {
|
|
681
|
+
method: method,
|
|
682
|
+
headers: {
|
|
683
|
+
'x-api-key': this.apiKey,
|
|
684
|
+
'Content-Type': 'application/json',
|
|
685
|
+
'User-Agent': `mcp-prompt-optimizer/${packageJson.version}`,
|
|
686
|
+
'Accept': 'application/json',
|
|
687
|
+
'Connection': 'close'
|
|
688
|
+
},
|
|
689
|
+
timeout: this.requestTimeout
|
|
690
|
+
};
|
|
691
|
+
|
|
692
|
+
const client = this.backendUrl.startsWith('https://') ? https : http;
|
|
693
|
+
const req = client.request(url, options, (res) => {
|
|
694
|
+
let responseData = '';
|
|
695
|
+
|
|
696
|
+
res.on('data', (chunk) => {
|
|
697
|
+
responseData += chunk;
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
res.on('end', () => {
|
|
701
|
+
try {
|
|
702
|
+
if (res.statusCode >= 200 && res.statusCode < 300) {
|
|
703
|
+
const parsed = JSON.parse(responseData);
|
|
704
|
+
resolve(parsed);
|
|
705
|
+
} else {
|
|
706
|
+
let errorMessage;
|
|
707
|
+
try {
|
|
708
|
+
const error = JSON.parse(responseData);
|
|
709
|
+
errorMessage = error.detail || error.message || `HTTP ${res.statusCode}`;
|
|
710
|
+
} catch {
|
|
711
|
+
errorMessage = `HTTP ${res.statusCode}: ${responseData}`;
|
|
712
|
+
}
|
|
713
|
+
reject(new Error(errorMessage));
|
|
714
|
+
}
|
|
715
|
+
} catch (parseError) {
|
|
716
|
+
reject(new Error(`Invalid response format: ${parseError.message}`));
|
|
717
|
+
}
|
|
718
|
+
});
|
|
719
|
+
});
|
|
720
|
+
|
|
721
|
+
req.on('error', (error) => {
|
|
722
|
+
if (error.code === 'ENOTFOUND') {
|
|
723
|
+
reject(new Error(`DNS resolution failed: Cannot resolve ${this.backendUrl.replace(/^https?:\/\//, '')}`));
|
|
724
|
+
} else if (error.code === 'ECONNREFUSED') {
|
|
725
|
+
reject(new Error(`Connection refused: Backend server may be down`));
|
|
726
|
+
} else if (error.code === 'ETIMEDOUT') {
|
|
727
|
+
reject(new Error(`Connection timeout: Backend server is not responding`));
|
|
728
|
+
} else if (error.code === 'ECONNRESET') {
|
|
729
|
+
reject(new Error(`Connection reset: Network instability detected`));
|
|
730
|
+
} else {
|
|
731
|
+
reject(new Error(`Network error: ${error.message}`));
|
|
732
|
+
}
|
|
733
|
+
});
|
|
734
|
+
|
|
735
|
+
req.on('timeout', () => {
|
|
736
|
+
req.destroy();
|
|
737
|
+
reject(new Error('Request timeout - backend may be unavailable'));
|
|
738
|
+
});
|
|
739
|
+
|
|
740
|
+
req.setTimeout(this.requestTimeout);
|
|
741
|
+
|
|
742
|
+
if (method !== 'GET' && data) {
|
|
743
|
+
req.write(JSON.stringify(data));
|
|
744
|
+
}
|
|
745
|
+
req.end();
|
|
746
|
+
});
|
|
747
|
+
}
|
|
695
748
|
}
|
|
696
749
|
|
|
697
750
|
module.exports = CloudApiKeyManager;
|
package/lib/check-status.js
CHANGED
|
@@ -10,7 +10,7 @@ async function checkStatus() {
|
|
|
10
10
|
if (!apiKey) {
|
|
11
11
|
console.error('❌ No API key found');
|
|
12
12
|
console.log('\n📝 Set your API key to check status:');
|
|
13
|
-
console.log(' export OPTIMIZER_API_KEY=sk-
|
|
13
|
+
console.log(' export OPTIMIZER_API_KEY=sk-local-your-key-here'); // Aligned with free tier/development
|
|
14
14
|
if (developmentMode) {
|
|
15
15
|
console.log('\n🧪 Development Mode Options:');
|
|
16
16
|
console.log(' export OPTIMIZER_API_KEY=sk-dev-test-key');
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-prompt-optimizer",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Professional cloud-based MCP server for AI-powered prompt optimization with intelligent context detection, template auto-save, optimization insights, personal model configuration via WebUI, team collaboration, enterprise-grade features, production resilience, and startup validation. Universal compatibility with Claude Desktop, Cursor, Windsurf, and 17+ MCP clients.",
|
|
3
|
+
"version": "2.2.3",
|
|
4
|
+
"description": "Professional cloud-based MCP server for AI-powered prompt optimization with intelligent context detection, Bayesian optimization, AG-UI real-time optimization, template auto-save, optimization insights, personal model configuration via WebUI, team collaboration, enterprise-grade features, production resilience, and startup validation. Universal compatibility with Claude Desktop, Cursor, Windsurf, and 17+ MCP clients.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"mcp-prompt-optimizer": "index.js"
|
|
@@ -23,8 +23,10 @@
|
|
|
23
23
|
"test:integration": "node tests/integration-test.js",
|
|
24
24
|
"test:comprehensive": "node tests/comprehensive-test.js",
|
|
25
25
|
"test:runner": "node tests/test-runner.js",
|
|
26
|
+
"test:simple": "node tests/simple-test.js",
|
|
26
27
|
"pretest": "npm run health-check",
|
|
27
|
-
"prepublishOnly": "npm run test:quick"
|
|
28
|
+
"prepublishOnly": "npm run test:quick",
|
|
29
|
+
"version": "echo 'Updating version...' && npm run test:quick"
|
|
28
30
|
},
|
|
29
31
|
"dependencies": {
|
|
30
32
|
"@modelcontextprotocol/sdk": "^1.15.1",
|
|
@@ -85,7 +87,17 @@
|
|
|
85
87
|
"windows",
|
|
86
88
|
"macos",
|
|
87
89
|
"linux",
|
|
88
|
-
"arm64"
|
|
90
|
+
"arm64",
|
|
91
|
+
"bayesian-optimization",
|
|
92
|
+
"ag-ui-real-time",
|
|
93
|
+
"streaming-optimization",
|
|
94
|
+
"websocket-support",
|
|
95
|
+
"performance-optimization",
|
|
96
|
+
"advanced-analytics",
|
|
97
|
+
"intelligent-context",
|
|
98
|
+
"ai-aware-rules",
|
|
99
|
+
"parameter-tuning",
|
|
100
|
+
"optimization-strategies"
|
|
89
101
|
],
|
|
90
102
|
"author": "Prompt Optimizer Team <support@promptoptimizer.help>",
|
|
91
103
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -100,7 +112,6 @@
|
|
|
100
112
|
"files": [
|
|
101
113
|
"index.js",
|
|
102
114
|
"lib/",
|
|
103
|
-
"tests/",
|
|
104
115
|
"README.md",
|
|
105
116
|
"CHANGELOG.md",
|
|
106
117
|
"CROSS-PLATFORM.md",
|
|
@@ -161,9 +172,73 @@
|
|
|
161
172
|
"description": "Enable development mode (true/false)",
|
|
162
173
|
"required": false,
|
|
163
174
|
"default": "false"
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
"name": "ENABLE_BAYESIAN_OPTIMIZATION",
|
|
178
|
+
"description": "Enable Bayesian optimization features (true/false)",
|
|
179
|
+
"required": false,
|
|
180
|
+
"default": "true"
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
"name": "ENABLE_AGUI_FEATURES",
|
|
184
|
+
"description": "Enable AG-UI real-time optimization features (true/false)",
|
|
185
|
+
"required": false,
|
|
186
|
+
"default": "true"
|
|
164
187
|
}
|
|
165
188
|
]
|
|
166
189
|
},
|
|
190
|
+
"features": {
|
|
191
|
+
"core": {
|
|
192
|
+
"ai_context_detection": true,
|
|
193
|
+
"template_management": true,
|
|
194
|
+
"optimization_insights": true,
|
|
195
|
+
"quota_management": true,
|
|
196
|
+
"multi_tier_support": true,
|
|
197
|
+
"error_handling": true,
|
|
198
|
+
"caching": true,
|
|
199
|
+
"fallback_modes": true
|
|
200
|
+
},
|
|
201
|
+
"advanced": {
|
|
202
|
+
"bayesian_optimization": true,
|
|
203
|
+
"ag_ui_real_time": true,
|
|
204
|
+
"streaming_optimization": true,
|
|
205
|
+
"intelligent_routing": true,
|
|
206
|
+
"performance_analytics": true,
|
|
207
|
+
"ai_aware_rules": true,
|
|
208
|
+
"context_aware_templates": true,
|
|
209
|
+
"parameter_tuning": true
|
|
210
|
+
},
|
|
211
|
+
"enterprise": {
|
|
212
|
+
"team_collaboration": true,
|
|
213
|
+
"advanced_analytics": true,
|
|
214
|
+
"custom_models": true,
|
|
215
|
+
"priority_support": true,
|
|
216
|
+
"sla_guarantees": true,
|
|
217
|
+
"dedicated_resources": true
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
"backend_alignment": {
|
|
221
|
+
"version": "production-v2.2.0-stable",
|
|
222
|
+
"api_version": "v1",
|
|
223
|
+
"endpoints_aligned": true,
|
|
224
|
+
"feature_parity": true,
|
|
225
|
+
"bayesian_support": true,
|
|
226
|
+
"agui_support": true,
|
|
227
|
+
"last_sync": "2025-09-25T00:00:00Z"
|
|
228
|
+
},
|
|
229
|
+
"release_notes": {
|
|
230
|
+
"v1.5.0": {
|
|
231
|
+
"major_features": [
|
|
232
|
+
"Bayesian optimization with parameter tuning",
|
|
233
|
+
"AG-UI real-time optimization capabilities",
|
|
234
|
+
"Enhanced AI context detection with weighted scoring",
|
|
235
|
+
"Advanced template search with AI-aware filtering"
|
|
236
|
+
],
|
|
237
|
+
"breaking_changes": [],
|
|
238
|
+
"migration_guide": "All existing functionality remains compatible. New features are opt-in via environment variables.",
|
|
239
|
+
"backend_compatibility": "Fully aligned with FastAPI Backend v2.1.0-bayesian"
|
|
240
|
+
}
|
|
241
|
+
},
|
|
167
242
|
"support": {
|
|
168
243
|
"email": "support@promptoptimizer.help",
|
|
169
244
|
"documentation": "https://promptoptimizer-blog.vercel.app/docs",
|