class SmartRagConfigurationOptimizer {
constructor(flowName, apiToken) {
this.flowName = flowName;
this.apiToken = apiToken;
this.baseUrl = `https://${flowName}.flows.graphorlm.com`;
}
async getAllNodes() {
const response = await fetch(`${this.baseUrl}/smart-rag`, {
headers: { 'Authorization': `Bearer ${this.apiToken}` }
});
if (!response.ok) {
throw new Error(`Failed to fetch nodes: ${response.statusText}`);
}
return await response.json();
}
async optimizeConfiguration(nodeId, targetProfile = 'balanced') {
const profiles = {
'precision': { topK: 5, description: 'High-precision, low resource usage' },
'balanced': { topK: 10, description: 'Balanced precision and coverage' },
'comprehensive': { topK: 20, description: 'High coverage, thorough results' },
'unlimited': { topK: null, description: 'Complete analysis, maximum resources' }
};
const profile = profiles[targetProfile];
if (!profile) {
throw new Error(`Invalid profile: ${targetProfile}. Available: ${Object.keys(profiles).join(', ')}`);
}
console.log(`π― Optimizing node ${nodeId} for ${targetProfile} profile`);
console.log(` Configuration: Top K = ${profile.topK || 'unlimited'}`);
console.log(` Description: ${profile.description}`);
const response = await fetch(`${this.baseUrl}/smart-rag/${nodeId}`, {
method: 'PATCH',
headers: {
'Authorization': `Bearer ${this.apiToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ config: { topK: profile.topK } })
});
if (!response.ok) {
throw new Error(`Optimization failed: ${response.statusText}`);
}
const result = await response.json();
console.log(`β
${result.message}`);
return result;
}
async batchOptimization(optimizations) {
console.log(`π Starting batch optimization for ${optimizations.length} nodes`);
const results = [];
for (const { nodeId, profile } of optimizations) {
try {
const result = await this.optimizeConfiguration(nodeId, profile);
results.push({ nodeId, profile, success: true, result });
// Small delay to avoid overwhelming the API
await new Promise(resolve => setTimeout(resolve, 500));
} catch (error) {
console.error(`β Failed to optimize ${nodeId}: ${error.message}`);
results.push({ nodeId, profile, success: false, error: error.message });
}
}
this.generateBatchReport(results);
return results;
}
generateBatchReport(results) {
console.log('\nπ Batch Optimization Report');
console.log('============================');
const successful = results.filter(r => r.success);
const failed = results.filter(r => !r.success);
console.log(`Total Operations: ${results.length}`);
console.log(`Successful: ${successful.length}`);
console.log(`Failed: ${failed.length}`);
if (successful.length > 0) {
console.log('\nβ
Successful Optimizations:');
successful.forEach(({ nodeId, profile }) => {
console.log(` ${nodeId} β ${profile} profile`);
});
}
if (failed.length > 0) {
console.log('\nβ Failed Optimizations:');
failed.forEach(({ nodeId, profile, error }) => {
console.log(` ${nodeId} (${profile}): ${error}`);
});
}
}
async recommendOptimizations() {
const nodes = await this.getAllNodes();
const recommendations = [];
console.log('π Analyzing nodes for optimization opportunities...\n');
for (const node of nodes) {
const config = node.data.config || {};
const result = node.data.result || {};
const topK = config.topK;
const nodeName = node.data.name;
let recommendation = null;
// Analysis logic
if (result.has_error) {
recommendation = {
nodeId: node.id,
nodeName,
currentTopK: topK,
issue: 'Node has errors',
suggestedProfile: 'precision',
reason: 'Reduce resource usage to address stability issues',
priority: 'high'
};
} else if (result.processing && topK > 20) {
recommendation = {
nodeId: node.id,
nodeName,
currentTopK: topK,
issue: 'Long processing time with high Top K',
suggestedProfile: 'balanced',
reason: 'Balance performance and quality',
priority: 'medium'
};
} else if (topK === null && !result.updatedMetrics) {
recommendation = {
nodeId: node.id,
nodeName,
currentTopK: topK,
issue: 'Unlimited processing without metrics',
suggestedProfile: 'comprehensive',
reason: 'Limit resource usage and enable monitoring',
priority: 'medium'
};
} else if (topK && topK < 3) {
recommendation = {
nodeId: node.id,
nodeName,
currentTopK: topK,
issue: 'Very low Top K may limit coverage',
suggestedProfile: 'balanced',
reason: 'Improve result coverage while maintaining efficiency',
priority: 'low'
};
}
if (recommendation) {
recommendations.push(recommendation);
}
}
this.printRecommendations(recommendations);
return recommendations;
}
printRecommendations(recommendations) {
if (recommendations.length === 0) {
console.log('β
No optimization recommendations - all nodes appear well-configured');
return;
}
console.log(`π‘ Found ${recommendations.length} optimization opportunities:\n`);
const byPriority = {
high: recommendations.filter(r => r.priority === 'high'),
medium: recommendations.filter(r => r.priority === 'medium'),
low: recommendations.filter(r => r.priority === 'low')
};
['high', 'medium', 'low'].forEach(priority => {
if (byPriority[priority].length > 0) {
const icon = priority === 'high' ? 'π΄' : priority === 'medium' ? 'π‘' : 'π’';
console.log(`${icon} ${priority.toUpperCase()} Priority (${byPriority[priority].length} items):`);
byPriority[priority].forEach(rec => {
console.log(` π ${rec.nodeName} (${rec.nodeId})`);
console.log(` Issue: ${rec.issue}`);
console.log(` Current Top K: ${rec.currentTopK || 'unlimited'}`);
console.log(` Suggested: ${rec.suggestedProfile} profile`);
console.log(` Reason: ${rec.reason}\n`);
});
}
});
}
}
// Usage examples
const optimizer = new SmartRagConfigurationOptimizer('my-rag-pipeline', 'YOUR_API_TOKEN');
// Single node optimization
optimizer.optimizeConfiguration('smart-rag-123', 'balanced').catch(console.error);
// Batch optimization
const batchOps = [
{ nodeId: 'smart-rag-123', profile: 'precision' },
{ nodeId: 'smart-rag-456', profile: 'balanced' },
{ nodeId: 'smart-rag-789', profile: 'comprehensive' }
];
optimizer.batchOptimization(batchOps).catch(console.error);
// Get recommendations
optimizer.recommendOptimizations().catch(console.error);