Merge commit 'd803bfe2b1fe7f5e219e50ac20d6801a0a58ac75' as 'vendor/ruvector'

This commit is contained in:
ruv
2026-02-28 14:39:40 -05:00
7854 changed files with 3522914 additions and 0 deletions

View File

@@ -0,0 +1,72 @@
/**
* ADVANCED TUTORIAL: Custom Learning System
*
* Extend the self-learning system with custom optimization strategies,
* domain-specific learning, and advanced evaluation metrics. Perfect for
* building production-grade adaptive AI systems.
*
* What you'll learn:
* - Creating custom evaluators
* - Domain-specific optimization
* - Advanced feedback loops
* - Multi-objective optimization
* - Transfer learning patterns
*
* Prerequisites:
* - Complete intermediate tutorials first
* - Set GEMINI_API_KEY environment variable
* - npm install dspy.ts @ruvector/agentic-synth
*
* Run: npx tsx examples/advanced/custom-learning-system.ts
*/
import { Prediction } from 'dspy.ts';
interface EvaluationMetrics {
accuracy: number;
creativity: number;
relevance: number;
engagement: number;
technicalQuality: number;
overall: number;
}
interface AdvancedLearningConfig {
domain: string;
objectives: string[];
weights: Record<string, number>;
learningStrategy: 'aggressive' | 'conservative' | 'adaptive';
convergenceThreshold: number;
diversityBonus: boolean;
transferLearning: boolean;
}
interface TrainingExample {
input: any;
expectedOutput: any;
quality: number;
metadata: {
domain: string;
difficulty: 'easy' | 'medium' | 'hard';
tags: string[];
};
}
interface Evaluator {
evaluate(output: Prediction, context: any): Promise<EvaluationMetrics>;
}
declare class EcommerceEvaluator implements Evaluator {
evaluate(output: Prediction, context: any): Promise<EvaluationMetrics>;
}
declare class AdvancedLearningSystem {
private lm;
private config;
private evaluator;
private knowledgeBase;
private promptStrategies;
constructor(config: AdvancedLearningConfig, evaluator: Evaluator);
private getTemperatureForStrategy;
learnFromExample(example: TrainingExample): Promise<void>;
train(examples: TrainingExample[]): Promise<void>;
private generate;
private findSimilarExamples;
private displayTrainingResults;
test(testCases: any[]): Promise<void>;
}
export { AdvancedLearningSystem, EcommerceEvaluator, AdvancedLearningConfig };
//# sourceMappingURL=custom-learning-system.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"custom-learning-system.d.ts","sourceRoot":"","sources":["custom-learning-system.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAsB,UAAU,EAAE,MAAM,SAAS,CAAC;AAIzD,UAAU,iBAAiB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;CACjB;AAGD,UAAU,sBAAsB;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,gBAAgB,EAAE,YAAY,GAAG,cAAc,GAAG,UAAU,CAAC;IAC7D,oBAAoB,EAAE,MAAM,CAAC;IAC7B,cAAc,EAAE,OAAO,CAAC;IACxB,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAGD,UAAU,eAAe;IACvB,KAAK,EAAE,GAAG,CAAC;IACX,cAAc,EAAE,GAAG,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE;QACR,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;QACvC,IAAI,EAAE,MAAM,EAAE,CAAC;KAChB,CAAC;CACH;AAGD,UAAU,SAAS;IACjB,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;CACxE;AAGD,cAAM,kBAAmB,YAAW,SAAS;IACrC,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAsG7E;AAGD,cAAM,sBAAsB;IAC1B,OAAO,CAAC,EAAE,CAAK;IACf,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,aAAa,CAAyB;IAC9C,OAAO,CAAC,gBAAgB,CAAkC;gBAE9C,MAAM,EAAE,sBAAsB,EAAE,SAAS,EAAE,SAAS;IAYhE,OAAO,CAAC,yBAAyB;IAS3B,gBAAgB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBzD,KAAK,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAwCzC,QAAQ;IA0BtB,OAAO,CAAC,mBAAmB;IAW3B,OAAO,CAAC,sBAAsB;IA4BxB,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAwD5C;AA+ED,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,CAAC"}

View File

@@ -0,0 +1,353 @@
"use strict";
/**
* ADVANCED TUTORIAL: Custom Learning System
*
* Extend the self-learning system with custom optimization strategies,
* domain-specific learning, and advanced evaluation metrics. Perfect for
* building production-grade adaptive AI systems.
*
* What you'll learn:
* - Creating custom evaluators
* - Domain-specific optimization
* - Advanced feedback loops
* - Multi-objective optimization
* - Transfer learning patterns
*
* Prerequisites:
* - Complete intermediate tutorials first
* - Set GEMINI_API_KEY environment variable
* - npm install dspy.ts @ruvector/agentic-synth
*
* Run: npx tsx examples/advanced/custom-learning-system.ts
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.EcommerceEvaluator = exports.AdvancedLearningSystem = void 0;
const dspy_ts_1 = require("dspy.ts");
// Domain-specific evaluator for e-commerce
class EcommerceEvaluator {
async evaluate(output, context) {
const metrics = {
accuracy: 0,
creativity: 0,
relevance: 0,
engagement: 0,
technicalQuality: 0,
overall: 0
};
// Accuracy: Check for required information
if (output.description && output.key_features) {
metrics.accuracy += 0.5;
// Check if key product attributes are mentioned
const desc = output.description.toLowerCase();
const productName = context.product_name.toLowerCase();
const category = context.category.toLowerCase();
if (desc.includes(productName.split(' ')[0])) {
metrics.accuracy += 0.25;
}
if (desc.includes(category)) {
metrics.accuracy += 0.25;
}
}
// Creativity: Check for unique, non-generic phrases
if (output.description) {
const genericPhrases = ['high quality', 'great product', 'best choice'];
const hasGenericPhrase = genericPhrases.some(phrase => output.description.toLowerCase().includes(phrase));
metrics.creativity = hasGenericPhrase ? 0.3 : 0.8;
// Bonus for specific details
const hasNumbers = /\d+/.test(output.description);
const hasSpecifics = /(\d+\s*(hours|days|years|gb|mb|kg|lbs))/i.test(output.description);
if (hasSpecifics)
metrics.creativity += 0.2;
}
// Relevance: Check alignment with category
const categoryKeywords = {
electronics: ['technology', 'device', 'digital', 'battery', 'power'],
fashion: ['style', 'design', 'material', 'comfort', 'wear'],
food: ['taste', 'flavor', 'nutrition', 'organic', 'fresh'],
fitness: ['workout', 'exercise', 'health', 'training', 'performance']
};
const category = context.category.toLowerCase();
const relevantKeywords = categoryKeywords[category] || [];
if (output.description) {
const desc = output.description.toLowerCase();
const matchedKeywords = relevantKeywords.filter(kw => desc.includes(kw));
metrics.relevance = Math.min(matchedKeywords.length / 3, 1.0);
}
// Engagement: Check for emotional appeal and calls to action
if (output.description) {
const desc = output.description.toLowerCase();
const emotionalWords = ['amazing', 'incredible', 'perfect', 'premium', 'exceptional', 'revolutionary'];
const actionWords = ['discover', 'experience', 'enjoy', 'upgrade', 'transform'];
const hasEmotion = emotionalWords.some(word => desc.includes(word));
const hasAction = actionWords.some(word => desc.includes(word));
metrics.engagement = (hasEmotion ? 0.5 : 0) + (hasAction ? 0.5 : 0);
}
// Technical Quality: Check structure and formatting
if (output.key_features && Array.isArray(output.key_features)) {
const features = output.key_features;
let techScore = 0;
// Optimal number of features
if (features.length >= 4 && features.length <= 6) {
techScore += 0.4;
}
// Feature formatting
const wellFormatted = features.filter(f => f.length >= 15 && f.length <= 60 && !f.endsWith('.'));
techScore += (wellFormatted.length / features.length) * 0.6;
metrics.technicalQuality = techScore;
}
// Calculate overall score with weights
metrics.overall = (metrics.accuracy * 0.25 +
metrics.creativity * 0.20 +
metrics.relevance * 0.25 +
metrics.engagement * 0.15 +
metrics.technicalQuality * 0.15);
return metrics;
}
}
exports.EcommerceEvaluator = EcommerceEvaluator;
// Advanced self-learning generator
class AdvancedLearningSystem {
constructor(config, evaluator) {
this.knowledgeBase = [];
this.promptStrategies = new Map();
this.config = config;
this.evaluator = evaluator;
this.lm = new dspy_ts_1.LM({
provider: 'google-genai',
model: 'gemini-2.0-flash-exp',
apiKey: process.env.GEMINI_API_KEY || '',
temperature: this.getTemperatureForStrategy()
});
}
getTemperatureForStrategy() {
switch (this.config.learningStrategy) {
case 'aggressive': return 0.9;
case 'conservative': return 0.5;
case 'adaptive': return 0.7;
}
}
// Learn from a single example
async learnFromExample(example) {
console.log(`\n🎯 Learning from example (${example.metadata.difficulty})...`);
const output = await this.generate(example.input);
const metrics = await this.evaluator.evaluate(output, example.input);
console.log(` Overall Quality: ${(metrics.overall * 100).toFixed(1)}%`);
console.log(` Accuracy: ${(metrics.accuracy * 100).toFixed(0)}% | Creativity: ${(metrics.creativity * 100).toFixed(0)}%`);
console.log(` Relevance: ${(metrics.relevance * 100).toFixed(0)}% | Engagement: ${(metrics.engagement * 100).toFixed(0)}%`);
// Store high-quality examples
if (metrics.overall >= 0.7) {
this.knowledgeBase.push({
...example,
quality: metrics.overall
});
console.log(` ✓ Added to knowledge base`);
}
}
// Train on a dataset
async train(examples) {
console.log('🏋️ Starting Advanced Training Session\n');
console.log('='.repeat(70));
console.log(`\nDomain: ${this.config.domain}`);
console.log(`Strategy: ${this.config.learningStrategy}`);
console.log(`Examples: ${examples.length}`);
console.log(`\nObjectives:`);
this.config.objectives.forEach(obj => console.log(`${obj}`));
console.log('\n' + '='.repeat(70));
// Group by difficulty
const byDifficulty = {
easy: examples.filter(e => e.metadata.difficulty === 'easy'),
medium: examples.filter(e => e.metadata.difficulty === 'medium'),
hard: examples.filter(e => e.metadata.difficulty === 'hard')
};
// Progressive learning: start with easy, move to hard
console.log('\n📚 Phase 1: Learning Basics (Easy Examples)');
console.log('─'.repeat(70));
for (const example of byDifficulty.easy) {
await this.learnFromExample(example);
}
console.log('\n📚 Phase 2: Intermediate Concepts (Medium Examples)');
console.log('─'.repeat(70));
for (const example of byDifficulty.medium) {
await this.learnFromExample(example);
}
console.log('\n📚 Phase 3: Advanced Patterns (Hard Examples)');
console.log('─'.repeat(70));
for (const example of byDifficulty.hard) {
await this.learnFromExample(example);
}
this.displayTrainingResults();
}
// Generate with learned knowledge
async generate(input) {
// Use knowledge base for few-shot learning
const similarExamples = this.findSimilarExamples(input, 3);
let enhancedDescription = 'Generate compelling product descriptions.';
if (similarExamples.length > 0) {
enhancedDescription += '\n\nLearn from these high-quality examples:\n';
similarExamples.forEach((ex, i) => {
enhancedDescription += `\nExample ${i + 1}:\n`;
enhancedDescription += `Input: ${JSON.stringify(ex.input)}\n`;
enhancedDescription += `Output: ${JSON.stringify(ex.expectedOutput)}`;
});
}
const signature = {
input: 'product_name: string, category: string, price: number',
output: 'description: string, key_features: string[]',
description: enhancedDescription
};
const generator = new dspy_ts_1.ChainOfThought(signature, { lm: this.lm });
return await generator.forward(input);
}
// Find similar examples from knowledge base
findSimilarExamples(input, count) {
// Simple similarity based on category match
const similar = this.knowledgeBase
.filter(ex => ex.input.category === input.category)
.sort((a, b) => b.quality - a.quality)
.slice(0, count);
return similar;
}
// Display training results
displayTrainingResults() {
console.log('\n\n' + '='.repeat(70));
console.log('\n🎓 TRAINING RESULTS\n');
console.log(`Knowledge Base: ${this.knowledgeBase.length} high-quality examples`);
if (this.knowledgeBase.length > 0) {
const avgQuality = this.knowledgeBase.reduce((sum, ex) => sum + ex.quality, 0) / this.knowledgeBase.length;
console.log(`Average Quality: ${(avgQuality * 100).toFixed(1)}%`);
// Group by category
const byCategory = {};
this.knowledgeBase.forEach(ex => {
const cat = ex.input.category;
byCategory[cat] = (byCategory[cat] || 0) + 1;
});
console.log(`\nLearned Categories:`);
Object.entries(byCategory).forEach(([cat, count]) => {
console.log(`${cat}: ${count} examples`);
});
}
console.log('\n✅ Training complete! System is ready for production.\n');
console.log('='.repeat(70) + '\n');
}
// Test the trained system
async test(testCases) {
console.log('\n🧪 Testing Trained System\n');
console.log('='.repeat(70) + '\n');
let totalMetrics = {
accuracy: 0,
creativity: 0,
relevance: 0,
engagement: 0,
technicalQuality: 0,
overall: 0
};
for (let i = 0; i < testCases.length; i++) {
const testCase = testCases[i];
console.log(`\nTest ${i + 1}/${testCases.length}: ${testCase.product_name}`);
console.log('─'.repeat(70));
const output = await this.generate(testCase);
const metrics = await this.evaluator.evaluate(output, testCase);
console.log(`\n📝 Generated:`);
console.log(` ${output.description}`);
console.log(`\n Features:`);
if (output.key_features) {
output.key_features.forEach((f) => console.log(`${f}`));
}
console.log(`\n📊 Metrics:`);
console.log(` Overall: ${(metrics.overall * 100).toFixed(1)}%`);
console.log(` Accuracy: ${(metrics.accuracy * 100).toFixed(0)}% | Creativity: ${(metrics.creativity * 100).toFixed(0)}%`);
console.log(` Relevance: ${(metrics.relevance * 100).toFixed(0)}% | Engagement: ${(metrics.engagement * 100).toFixed(0)}%`);
console.log(` Technical: ${(metrics.technicalQuality * 100).toFixed(0)}%`);
// Aggregate metrics
Object.keys(totalMetrics).forEach(key => {
totalMetrics[key] += metrics[key];
});
}
// Average metrics
Object.keys(totalMetrics).forEach(key => {
totalMetrics[key] /= testCases.length;
});
console.log('\n\n' + '='.repeat(70));
console.log('\n📈 TEST SUMMARY\n');
console.log(`Overall Performance: ${(totalMetrics.overall * 100).toFixed(1)}%`);
console.log(`\nDetailed Metrics:`);
console.log(` Accuracy: ${(totalMetrics.accuracy * 100).toFixed(1)}%`);
console.log(` Creativity: ${(totalMetrics.creativity * 100).toFixed(1)}%`);
console.log(` Relevance: ${(totalMetrics.relevance * 100).toFixed(1)}%`);
console.log(` Engagement: ${(totalMetrics.engagement * 100).toFixed(1)}%`);
console.log(` Technical Quality: ${(totalMetrics.technicalQuality * 100).toFixed(1)}%`);
console.log('\n' + '='.repeat(70) + '\n');
}
}
exports.AdvancedLearningSystem = AdvancedLearningSystem;
// Main execution
async function runAdvancedLearning() {
const config = {
domain: 'ecommerce',
objectives: [
'Generate accurate product descriptions',
'Maintain high creativity and engagement',
'Ensure category-specific relevance'
],
weights: {
accuracy: 0.25,
creativity: 0.20,
relevance: 0.25,
engagement: 0.15,
technical: 0.15
},
learningStrategy: 'adaptive',
convergenceThreshold: 0.85,
diversityBonus: true,
transferLearning: true
};
const evaluator = new EcommerceEvaluator();
const system = new AdvancedLearningSystem(config, evaluator);
// Training examples
const trainingExamples = [
{
input: { product_name: 'Smart Watch', category: 'electronics', price: 299 },
expectedOutput: {
description: 'Advanced fitness tracking meets elegant design in this premium smartwatch',
key_features: ['Heart rate monitoring', '7-day battery', 'Water resistant', 'GPS tracking']
},
quality: 0.9,
metadata: { domain: 'ecommerce', difficulty: 'easy', tags: ['electronics', 'wearable'] }
},
{
input: { product_name: 'Yoga Mat', category: 'fitness', price: 49 },
expectedOutput: {
description: 'Professional-grade yoga mat with superior grip and cushioning for all practice levels',
key_features: ['6mm thickness', 'Non-slip surface', 'Eco-friendly material', 'Easy to clean']
},
quality: 0.85,
metadata: { domain: 'ecommerce', difficulty: 'easy', tags: ['fitness', 'yoga'] }
},
{
input: { product_name: 'Mechanical Keyboard', category: 'electronics', price: 159 },
expectedOutput: {
description: 'Tactile perfection for enthusiasts with customizable RGB and premium switches',
key_features: ['Cherry MX switches', 'RGB backlighting', 'Programmable keys', 'Aluminum frame']
},
quality: 0.92,
metadata: { domain: 'ecommerce', difficulty: 'medium', tags: ['electronics', 'gaming'] }
}
];
// Train the system
await system.train(trainingExamples);
// Test the system
const testCases = [
{ product_name: 'Wireless Earbuds', category: 'electronics', price: 129 },
{ product_name: 'Resistance Bands Set', category: 'fitness', price: 29 },
{ product_name: 'Laptop Stand', category: 'electronics', price: 59 }
];
await system.test(testCases);
}
// Run the example
if (import.meta.url === `file://${process.argv[1]}`) {
runAdvancedLearning().catch(error => {
console.error('❌ Advanced learning failed:', error);
process.exit(1);
});
}
//# sourceMappingURL=custom-learning-system.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,460 @@
/**
* ADVANCED TUTORIAL: Custom Learning System
*
* Extend the self-learning system with custom optimization strategies,
* domain-specific learning, and advanced evaluation metrics. Perfect for
* building production-grade adaptive AI systems.
*
* What you'll learn:
* - Creating custom evaluators
* - Domain-specific optimization
* - Advanced feedback loops
* - Multi-objective optimization
* - Transfer learning patterns
*
* Prerequisites:
* - Complete intermediate tutorials first
* - Set GEMINI_API_KEY environment variable
* - npm install dspy.ts @ruvector/agentic-synth
*
* Run: npx tsx examples/advanced/custom-learning-system.ts
*/
import { LM, ChainOfThought, Prediction } from 'dspy.ts';
import { AgenticSynth } from '@ruvector/agentic-synth';
// Multi-objective evaluation metrics
interface EvaluationMetrics {
accuracy: number;
creativity: number;
relevance: number;
engagement: number;
technicalQuality: number;
overall: number;
}
// Advanced learning configuration
interface AdvancedLearningConfig {
domain: string;
objectives: string[];
weights: Record<string, number>;
learningStrategy: 'aggressive' | 'conservative' | 'adaptive';
convergenceThreshold: number;
diversityBonus: boolean;
transferLearning: boolean;
}
// Training example with rich metadata
interface TrainingExample {
input: any;
expectedOutput: any;
quality: number;
metadata: {
domain: string;
difficulty: 'easy' | 'medium' | 'hard';
tags: string[];
};
}
// Custom evaluator interface
interface Evaluator {
evaluate(output: Prediction, context: any): Promise<EvaluationMetrics>;
}
// Domain-specific evaluator for e-commerce
class EcommerceEvaluator implements Evaluator {
async evaluate(output: Prediction, context: any): Promise<EvaluationMetrics> {
const metrics: EvaluationMetrics = {
accuracy: 0,
creativity: 0,
relevance: 0,
engagement: 0,
technicalQuality: 0,
overall: 0
};
// Accuracy: Check for required information
if (output.description && output.key_features) {
metrics.accuracy += 0.5;
// Check if key product attributes are mentioned
const desc = output.description.toLowerCase();
const productName = context.product_name.toLowerCase();
const category = context.category.toLowerCase();
if (desc.includes(productName.split(' ')[0])) {
metrics.accuracy += 0.25;
}
if (desc.includes(category)) {
metrics.accuracy += 0.25;
}
}
// Creativity: Check for unique, non-generic phrases
if (output.description) {
const genericPhrases = ['high quality', 'great product', 'best choice'];
const hasGenericPhrase = genericPhrases.some(phrase =>
output.description.toLowerCase().includes(phrase)
);
metrics.creativity = hasGenericPhrase ? 0.3 : 0.8;
// Bonus for specific details
const hasNumbers = /\d+/.test(output.description);
const hasSpecifics = /(\d+\s*(hours|days|years|gb|mb|kg|lbs))/i.test(output.description);
if (hasSpecifics) metrics.creativity += 0.2;
}
// Relevance: Check alignment with category
const categoryKeywords: Record<string, string[]> = {
electronics: ['technology', 'device', 'digital', 'battery', 'power'],
fashion: ['style', 'design', 'material', 'comfort', 'wear'],
food: ['taste', 'flavor', 'nutrition', 'organic', 'fresh'],
fitness: ['workout', 'exercise', 'health', 'training', 'performance']
};
const category = context.category.toLowerCase();
const relevantKeywords = categoryKeywords[category] || [];
if (output.description) {
const desc = output.description.toLowerCase();
const matchedKeywords = relevantKeywords.filter(kw => desc.includes(kw));
metrics.relevance = Math.min(matchedKeywords.length / 3, 1.0);
}
// Engagement: Check for emotional appeal and calls to action
if (output.description) {
const desc = output.description.toLowerCase();
const emotionalWords = ['amazing', 'incredible', 'perfect', 'premium', 'exceptional', 'revolutionary'];
const actionWords = ['discover', 'experience', 'enjoy', 'upgrade', 'transform'];
const hasEmotion = emotionalWords.some(word => desc.includes(word));
const hasAction = actionWords.some(word => desc.includes(word));
metrics.engagement = (hasEmotion ? 0.5 : 0) + (hasAction ? 0.5 : 0);
}
// Technical Quality: Check structure and formatting
if (output.key_features && Array.isArray(output.key_features)) {
const features = output.key_features;
let techScore = 0;
// Optimal number of features
if (features.length >= 4 && features.length <= 6) {
techScore += 0.4;
}
// Feature formatting
const wellFormatted = features.filter(f =>
f.length >= 15 && f.length <= 60 && !f.endsWith('.')
);
techScore += (wellFormatted.length / features.length) * 0.6;
metrics.technicalQuality = techScore;
}
// Calculate overall score with weights
metrics.overall = (
metrics.accuracy * 0.25 +
metrics.creativity * 0.20 +
metrics.relevance * 0.25 +
metrics.engagement * 0.15 +
metrics.technicalQuality * 0.15
);
return metrics;
}
}
// Advanced self-learning generator
class AdvancedLearningSystem {
private lm: LM;
private config: AdvancedLearningConfig;
private evaluator: Evaluator;
private knowledgeBase: TrainingExample[] = [];
private promptStrategies: Map<string, number> = new Map();
constructor(config: AdvancedLearningConfig, evaluator: Evaluator) {
this.config = config;
this.evaluator = evaluator;
this.lm = new LM({
provider: 'google-genai',
model: 'gemini-2.0-flash-exp',
apiKey: process.env.GEMINI_API_KEY || '',
temperature: this.getTemperatureForStrategy()
});
}
private getTemperatureForStrategy(): number {
switch (this.config.learningStrategy) {
case 'aggressive': return 0.9;
case 'conservative': return 0.5;
case 'adaptive': return 0.7;
}
}
// Learn from a single example
async learnFromExample(example: TrainingExample): Promise<void> {
console.log(`\n🎯 Learning from example (${example.metadata.difficulty})...`);
const output = await this.generate(example.input);
const metrics = await this.evaluator.evaluate(output, example.input);
console.log(` Overall Quality: ${(metrics.overall * 100).toFixed(1)}%`);
console.log(` Accuracy: ${(metrics.accuracy * 100).toFixed(0)}% | Creativity: ${(metrics.creativity * 100).toFixed(0)}%`);
console.log(` Relevance: ${(metrics.relevance * 100).toFixed(0)}% | Engagement: ${(metrics.engagement * 100).toFixed(0)}%`);
// Store high-quality examples
if (metrics.overall >= 0.7) {
this.knowledgeBase.push({
...example,
quality: metrics.overall
});
console.log(` ✓ Added to knowledge base`);
}
}
// Train on a dataset
async train(examples: TrainingExample[]): Promise<void> {
console.log('🏋️ Starting Advanced Training Session\n');
console.log('=' .repeat(70));
console.log(`\nDomain: ${this.config.domain}`);
console.log(`Strategy: ${this.config.learningStrategy}`);
console.log(`Examples: ${examples.length}`);
console.log(`\nObjectives:`);
this.config.objectives.forEach(obj => console.log(`${obj}`));
console.log('\n' + '=' .repeat(70));
// Group by difficulty
const byDifficulty = {
easy: examples.filter(e => e.metadata.difficulty === 'easy'),
medium: examples.filter(e => e.metadata.difficulty === 'medium'),
hard: examples.filter(e => e.metadata.difficulty === 'hard')
};
// Progressive learning: start with easy, move to hard
console.log('\n📚 Phase 1: Learning Basics (Easy Examples)');
console.log('─'.repeat(70));
for (const example of byDifficulty.easy) {
await this.learnFromExample(example);
}
console.log('\n📚 Phase 2: Intermediate Concepts (Medium Examples)');
console.log('─'.repeat(70));
for (const example of byDifficulty.medium) {
await this.learnFromExample(example);
}
console.log('\n📚 Phase 3: Advanced Patterns (Hard Examples)');
console.log('─'.repeat(70));
for (const example of byDifficulty.hard) {
await this.learnFromExample(example);
}
this.displayTrainingResults();
}
// Generate with learned knowledge
private async generate(input: any): Promise<Prediction> {
// Use knowledge base for few-shot learning
const similarExamples = this.findSimilarExamples(input, 3);
let enhancedDescription = 'Generate compelling product descriptions.';
if (similarExamples.length > 0) {
enhancedDescription += '\n\nLearn from these high-quality examples:\n';
similarExamples.forEach((ex, i) => {
enhancedDescription += `\nExample ${i + 1}:\n`;
enhancedDescription += `Input: ${JSON.stringify(ex.input)}\n`;
enhancedDescription += `Output: ${JSON.stringify(ex.expectedOutput)}`;
});
}
const signature = {
input: 'product_name: string, category: string, price: number',
output: 'description: string, key_features: string[]',
description: enhancedDescription
};
const generator = new ChainOfThought(signature, { lm: this.lm });
return await generator.forward(input);
}
// Find similar examples from knowledge base
private findSimilarExamples(input: any, count: number): TrainingExample[] {
// Simple similarity based on category match
const similar = this.knowledgeBase
.filter(ex => ex.input.category === input.category)
.sort((a, b) => b.quality - a.quality)
.slice(0, count);
return similar;
}
// Display training results
private displayTrainingResults(): void {
console.log('\n\n' + '=' .repeat(70));
console.log('\n🎓 TRAINING RESULTS\n');
console.log(`Knowledge Base: ${this.knowledgeBase.length} high-quality examples`);
if (this.knowledgeBase.length > 0) {
const avgQuality = this.knowledgeBase.reduce((sum, ex) => sum + ex.quality, 0) / this.knowledgeBase.length;
console.log(`Average Quality: ${(avgQuality * 100).toFixed(1)}%`);
// Group by category
const byCategory: Record<string, number> = {};
this.knowledgeBase.forEach(ex => {
const cat = ex.input.category;
byCategory[cat] = (byCategory[cat] || 0) + 1;
});
console.log(`\nLearned Categories:`);
Object.entries(byCategory).forEach(([cat, count]) => {
console.log(`${cat}: ${count} examples`);
});
}
console.log('\n✅ Training complete! System is ready for production.\n');
console.log('=' .repeat(70) + '\n');
}
// Test the trained system
async test(testCases: any[]): Promise<void> {
console.log('\n🧪 Testing Trained System\n');
console.log('=' .repeat(70) + '\n');
let totalMetrics: EvaluationMetrics = {
accuracy: 0,
creativity: 0,
relevance: 0,
engagement: 0,
technicalQuality: 0,
overall: 0
};
for (let i = 0; i < testCases.length; i++) {
const testCase = testCases[i];
console.log(`\nTest ${i + 1}/${testCases.length}: ${testCase.product_name}`);
console.log('─'.repeat(70));
const output = await this.generate(testCase);
const metrics = await this.evaluator.evaluate(output, testCase);
console.log(`\n📝 Generated:`);
console.log(` ${output.description}`);
console.log(`\n Features:`);
if (output.key_features) {
output.key_features.forEach((f: string) => console.log(`${f}`));
}
console.log(`\n📊 Metrics:`);
console.log(` Overall: ${(metrics.overall * 100).toFixed(1)}%`);
console.log(` Accuracy: ${(metrics.accuracy * 100).toFixed(0)}% | Creativity: ${(metrics.creativity * 100).toFixed(0)}%`);
console.log(` Relevance: ${(metrics.relevance * 100).toFixed(0)}% | Engagement: ${(metrics.engagement * 100).toFixed(0)}%`);
console.log(` Technical: ${(metrics.technicalQuality * 100).toFixed(0)}%`);
// Aggregate metrics
Object.keys(totalMetrics).forEach(key => {
totalMetrics[key as keyof EvaluationMetrics] += metrics[key as keyof EvaluationMetrics];
});
}
// Average metrics
Object.keys(totalMetrics).forEach(key => {
totalMetrics[key as keyof EvaluationMetrics] /= testCases.length;
});
console.log('\n\n' + '=' .repeat(70));
console.log('\n📈 TEST SUMMARY\n');
console.log(`Overall Performance: ${(totalMetrics.overall * 100).toFixed(1)}%`);
console.log(`\nDetailed Metrics:`);
console.log(` Accuracy: ${(totalMetrics.accuracy * 100).toFixed(1)}%`);
console.log(` Creativity: ${(totalMetrics.creativity * 100).toFixed(1)}%`);
console.log(` Relevance: ${(totalMetrics.relevance * 100).toFixed(1)}%`);
console.log(` Engagement: ${(totalMetrics.engagement * 100).toFixed(1)}%`);
console.log(` Technical Quality: ${(totalMetrics.technicalQuality * 100).toFixed(1)}%`);
console.log('\n' + '=' .repeat(70) + '\n');
}
}
// Main execution
async function runAdvancedLearning() {
const config: AdvancedLearningConfig = {
domain: 'ecommerce',
objectives: [
'Generate accurate product descriptions',
'Maintain high creativity and engagement',
'Ensure category-specific relevance'
],
weights: {
accuracy: 0.25,
creativity: 0.20,
relevance: 0.25,
engagement: 0.15,
technical: 0.15
},
learningStrategy: 'adaptive',
convergenceThreshold: 0.85,
diversityBonus: true,
transferLearning: true
};
const evaluator = new EcommerceEvaluator();
const system = new AdvancedLearningSystem(config, evaluator);
// Training examples
const trainingExamples: TrainingExample[] = [
{
input: { product_name: 'Smart Watch', category: 'electronics', price: 299 },
expectedOutput: {
description: 'Advanced fitness tracking meets elegant design in this premium smartwatch',
key_features: ['Heart rate monitoring', '7-day battery', 'Water resistant', 'GPS tracking']
},
quality: 0.9,
metadata: { domain: 'ecommerce', difficulty: 'easy', tags: ['electronics', 'wearable'] }
},
{
input: { product_name: 'Yoga Mat', category: 'fitness', price: 49 },
expectedOutput: {
description: 'Professional-grade yoga mat with superior grip and cushioning for all practice levels',
key_features: ['6mm thickness', 'Non-slip surface', 'Eco-friendly material', 'Easy to clean']
},
quality: 0.85,
metadata: { domain: 'ecommerce', difficulty: 'easy', tags: ['fitness', 'yoga'] }
},
{
input: { product_name: 'Mechanical Keyboard', category: 'electronics', price: 159 },
expectedOutput: {
description: 'Tactile perfection for enthusiasts with customizable RGB and premium switches',
key_features: ['Cherry MX switches', 'RGB backlighting', 'Programmable keys', 'Aluminum frame']
},
quality: 0.92,
metadata: { domain: 'ecommerce', difficulty: 'medium', tags: ['electronics', 'gaming'] }
}
];
// Train the system
await system.train(trainingExamples);
// Test the system
const testCases = [
{ product_name: 'Wireless Earbuds', category: 'electronics', price: 129 },
{ product_name: 'Resistance Bands Set', category: 'fitness', price: 29 },
{ product_name: 'Laptop Stand', category: 'electronics', price: 59 }
];
await system.test(testCases);
}
// Run the example
if (import.meta.url === `file://${process.argv[1]}`) {
runAdvancedLearning().catch(error => {
console.error('❌ Advanced learning failed:', error);
process.exit(1);
});
}
export { AdvancedLearningSystem, EcommerceEvaluator, AdvancedLearningConfig };

View File

@@ -0,0 +1,83 @@
/**
* ADVANCED TUTORIAL: Production Pipeline
*
* Build a complete production-ready data generation pipeline with:
* - Error handling and retry logic
* - Monitoring and metrics
* - Rate limiting and cost controls
* - Batch processing and caching
* - Quality validation
*
* What you'll learn:
* - Production-grade error handling
* - Performance monitoring
* - Cost optimization
* - Scalability patterns
* - Deployment best practices
*
* Prerequisites:
* - Complete previous tutorials
* - Set GEMINI_API_KEY environment variable
* - npm install @ruvector/agentic-synth
*
* Run: npx tsx examples/advanced/production-pipeline.ts
*/
import { GenerationResult } from '@ruvector/agentic-synth';
interface PipelineConfig {
maxRetries: number;
retryDelay: number;
batchSize: number;
maxConcurrency: number;
qualityThreshold: number;
costBudget: number;
rateLimitPerMinute: number;
enableCaching: boolean;
outputDirectory: string;
}
interface PipelineMetrics {
totalRequests: number;
successfulRequests: number;
failedRequests: number;
totalDuration: number;
totalCost: number;
averageQuality: number;
cacheHits: number;
retries: number;
errors: Array<{
timestamp: Date;
error: string;
context: any;
}>;
}
interface QualityValidator {
validate(data: any): {
valid: boolean;
score: number;
issues: string[];
};
}
declare class ProductionPipeline {
private config;
private synth;
private metrics;
private requestsThisMinute;
private minuteStartTime;
constructor(config?: Partial<PipelineConfig>);
private checkRateLimit;
private checkCostBudget;
private generateWithRetry;
private processBatch;
run(requests: any[], validator?: QualityValidator): Promise<GenerationResult[]>;
private saveResults;
private displayMetrics;
getMetrics(): PipelineMetrics;
}
declare class ProductQualityValidator implements QualityValidator {
validate(data: any[]): {
valid: boolean;
score: number;
issues: string[];
};
}
export { ProductionPipeline, ProductQualityValidator, PipelineConfig, PipelineMetrics };
//# sourceMappingURL=production-pipeline.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"production-pipeline.d.ts","sourceRoot":"","sources":["production-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAgB,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAKzE,UAAU,cAAc;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;CACzB;AAGD,UAAU,eAAe;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,KAAK,CAAC;QAAE,SAAS,EAAE,IAAI,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,GAAG,CAAA;KAAE,CAAC,CAAC;CACjE;AAGD,UAAU,gBAAgB;IACxB,QAAQ,CAAC,IAAI,EAAE,GAAG,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CAC1E;AAGD,cAAM,kBAAkB;IACtB,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,kBAAkB,CAAa;IACvC,OAAO,CAAC,eAAe,CAAsB;gBAEjC,MAAM,GAAE,OAAO,CAAC,cAAc,CAAM;YA0ClC,cAAc;IAoB5B,OAAO,CAAC,eAAe;YAOT,iBAAiB;YAqDjB,YAAY;IAyCpB,GAAG,CACP,QAAQ,EAAE,GAAG,EAAE,EACf,SAAS,CAAC,EAAE,gBAAgB,GAC3B,OAAO,CAAC,gBAAgB,EAAE,CAAC;YA4DhB,WAAW;IA6BzB,OAAO,CAAC,cAAc;IAuCtB,UAAU,IAAI,eAAe;CAG9B;AAGD,cAAM,uBAAwB,YAAW,gBAAgB;IACvD,QAAQ,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE;CAyB3E;AAiDD,OAAO,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,cAAc,EAAE,eAAe,EAAE,CAAC"}

View File

@@ -0,0 +1,341 @@
"use strict";
/**
* ADVANCED TUTORIAL: Production Pipeline
*
* Build a complete production-ready data generation pipeline with:
* - Error handling and retry logic
* - Monitoring and metrics
* - Rate limiting and cost controls
* - Batch processing and caching
* - Quality validation
*
* What you'll learn:
* - Production-grade error handling
* - Performance monitoring
* - Cost optimization
* - Scalability patterns
* - Deployment best practices
*
* Prerequisites:
* - Complete previous tutorials
* - Set GEMINI_API_KEY environment variable
* - npm install @ruvector/agentic-synth
*
* Run: npx tsx examples/advanced/production-pipeline.ts
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProductQualityValidator = exports.ProductionPipeline = void 0;
const agentic_synth_1 = require("@ruvector/agentic-synth");
const fs_1 = require("fs");
const path_1 = require("path");
// Production-grade pipeline
class ProductionPipeline {
constructor(config = {}) {
this.requestsThisMinute = 0;
this.minuteStartTime = Date.now();
this.config = {
maxRetries: config.maxRetries || 3,
retryDelay: config.retryDelay || 1000,
batchSize: config.batchSize || 10,
maxConcurrency: config.maxConcurrency || 3,
qualityThreshold: config.qualityThreshold || 0.7,
costBudget: config.costBudget || 10.0,
rateLimitPerMinute: config.rateLimitPerMinute || 60,
enableCaching: config.enableCaching !== false,
outputDirectory: config.outputDirectory || './output'
};
this.synth = new agentic_synth_1.AgenticSynth({
provider: 'gemini',
apiKey: process.env.GEMINI_API_KEY,
model: 'gemini-2.0-flash-exp',
cacheStrategy: this.config.enableCaching ? 'memory' : 'none',
cacheTTL: 3600,
maxRetries: this.config.maxRetries,
timeout: 30000
});
this.metrics = {
totalRequests: 0,
successfulRequests: 0,
failedRequests: 0,
totalDuration: 0,
totalCost: 0,
averageQuality: 0,
cacheHits: 0,
retries: 0,
errors: []
};
// Ensure output directory exists
if (!(0, fs_1.existsSync)(this.config.outputDirectory)) {
(0, fs_1.mkdirSync)(this.config.outputDirectory, { recursive: true });
}
}
// Rate limiting check
async checkRateLimit() {
const now = Date.now();
const elapsedMinutes = (now - this.minuteStartTime) / 60000;
if (elapsedMinutes >= 1) {
// Reset counter for new minute
this.requestsThisMinute = 0;
this.minuteStartTime = now;
}
if (this.requestsThisMinute >= this.config.rateLimitPerMinute) {
const waitTime = 60000 - (now - this.minuteStartTime);
console.log(`⏳ Rate limit reached, waiting ${Math.ceil(waitTime / 1000)}s...`);
await new Promise(resolve => setTimeout(resolve, waitTime));
this.requestsThisMinute = 0;
this.minuteStartTime = Date.now();
}
}
// Cost check
checkCostBudget() {
if (this.metrics.totalCost >= this.config.costBudget) {
throw new Error(`Cost budget exceeded: $${this.metrics.totalCost.toFixed(4)} >= $${this.config.costBudget}`);
}
}
// Generate with retry logic
async generateWithRetry(options, attempt = 1) {
try {
await this.checkRateLimit();
this.checkCostBudget();
this.requestsThisMinute++;
this.metrics.totalRequests++;
const startTime = Date.now();
const result = await this.synth.generateStructured(options);
const duration = Date.now() - startTime;
this.metrics.totalDuration += duration;
this.metrics.successfulRequests++;
if (result.metadata.cached) {
this.metrics.cacheHits++;
}
// Estimate cost (rough approximation)
const estimatedCost = result.metadata.cached ? 0 : 0.0001;
this.metrics.totalCost += estimatedCost;
return result;
}
catch (error) {
const errorMsg = error instanceof Error ? error.message : 'Unknown error';
if (attempt < this.config.maxRetries) {
this.metrics.retries++;
console.log(`⚠️ Attempt ${attempt} failed, retrying... (${errorMsg})`);
await new Promise(resolve => setTimeout(resolve, this.config.retryDelay * attempt));
return this.generateWithRetry(options, attempt + 1);
}
else {
this.metrics.failedRequests++;
this.metrics.errors.push({
timestamp: new Date(),
error: errorMsg,
context: options
});
throw error;
}
}
}
// Process a single batch
async processBatch(requests, validator) {
const results = [];
// Process with concurrency control
for (let i = 0; i < requests.length; i += this.config.maxConcurrency) {
const batch = requests.slice(i, i + this.config.maxConcurrency);
const batchResults = await Promise.allSettled(batch.map(req => this.generateWithRetry(req)));
batchResults.forEach((result, idx) => {
if (result.status === 'fulfilled') {
const genResult = result.value;
// Validate quality if validator provided
if (validator) {
const validation = validator.validate(genResult.data);
if (validation.valid) {
results.push(genResult);
}
else {
console.log(`⚠️ Quality validation failed (score: ${validation.score.toFixed(2)})`);
console.log(` Issues: ${validation.issues.join(', ')}`);
}
}
else {
results.push(genResult);
}
}
else {
console.error(`❌ Batch item ${i + idx} failed:`, result.reason);
}
});
}
return results;
}
// Main pipeline execution
async run(requests, validator) {
console.log('🏭 Starting Production Pipeline\n');
console.log('='.repeat(70));
console.log(`\nConfiguration:`);
console.log(` Total Requests: ${requests.length}`);
console.log(` Batch Size: ${this.config.batchSize}`);
console.log(` Max Concurrency: ${this.config.maxConcurrency}`);
console.log(` Max Retries: ${this.config.maxRetries}`);
console.log(` Cost Budget: $${this.config.costBudget}`);
console.log(` Rate Limit: ${this.config.rateLimitPerMinute}/min`);
console.log(` Caching: ${this.config.enableCaching ? 'Enabled' : 'Disabled'}`);
console.log(` Output: ${this.config.outputDirectory}`);
console.log('\n' + '='.repeat(70) + '\n');
const startTime = Date.now();
const allResults = [];
// Split into batches
const batches = [];
for (let i = 0; i < requests.length; i += this.config.batchSize) {
batches.push(requests.slice(i, i + this.config.batchSize));
}
console.log(`📦 Processing ${batches.length} batches...\n`);
// Process each batch
for (let i = 0; i < batches.length; i++) {
console.log(`\nBatch ${i + 1}/${batches.length} (${batches[i].length} items)`);
console.log('─'.repeat(70));
try {
const batchResults = await this.processBatch(batches[i], validator);
allResults.push(...batchResults);
console.log(`✓ Batch complete: ${batchResults.length}/${batches[i].length} successful`);
console.log(` Cost so far: $${this.metrics.totalCost.toFixed(4)}`);
console.log(` Cache hits: ${this.metrics.cacheHits}`);
}
catch (error) {
console.error(`✗ Batch failed:`, error instanceof Error ? error.message : 'Unknown error');
if (error instanceof Error && error.message.includes('budget')) {
console.log('\n⚠ Cost budget exceeded, stopping pipeline...');
break;
}
}
}
const totalTime = Date.now() - startTime;
// Save results
await this.saveResults(allResults);
// Display metrics
this.displayMetrics(totalTime);
return allResults;
}
// Save results to disk
async saveResults(results) {
try {
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const filename = `generation-${timestamp}.json`;
const filepath = (0, path_1.join)(this.config.outputDirectory, filename);
const output = {
timestamp: new Date(),
results: results.map(r => r.data),
metadata: {
count: results.length,
metrics: this.metrics
}
};
(0, fs_1.writeFileSync)(filepath, JSON.stringify(output, null, 2));
console.log(`\n💾 Results saved to: ${filepath}`);
// Save metrics separately
const metricsFile = (0, path_1.join)(this.config.outputDirectory, `metrics-${timestamp}.json`);
(0, fs_1.writeFileSync)(metricsFile, JSON.stringify(this.metrics, null, 2));
console.log(`📊 Metrics saved to: ${metricsFile}`);
}
catch (error) {
console.error('⚠️ Failed to save results:', error instanceof Error ? error.message : 'Unknown error');
}
}
// Display comprehensive metrics
displayMetrics(totalTime) {
console.log('\n\n' + '='.repeat(70));
console.log('\n📊 PIPELINE METRICS\n');
const successRate = (this.metrics.successfulRequests / this.metrics.totalRequests) * 100;
const avgDuration = this.metrics.totalDuration / this.metrics.successfulRequests;
const cacheHitRate = (this.metrics.cacheHits / this.metrics.totalRequests) * 100;
console.log('Performance:');
console.log(` Total Time: ${(totalTime / 1000).toFixed(2)}s`);
console.log(` Avg Request Time: ${avgDuration.toFixed(0)}ms`);
console.log(` Throughput: ${(this.metrics.successfulRequests / (totalTime / 1000)).toFixed(2)} req/s`);
console.log('\nReliability:');
console.log(` Total Requests: ${this.metrics.totalRequests}`);
console.log(` Successful: ${this.metrics.successfulRequests} (${successRate.toFixed(1)}%)`);
console.log(` Failed: ${this.metrics.failedRequests}`);
console.log(` Retries: ${this.metrics.retries}`);
console.log('\nCost & Efficiency:');
console.log(` Total Cost: $${this.metrics.totalCost.toFixed(4)}`);
console.log(` Avg Cost/Request: $${(this.metrics.totalCost / this.metrics.totalRequests).toFixed(6)}`);
console.log(` Cache Hit Rate: ${cacheHitRate.toFixed(1)}%`);
console.log(` Cost Savings from Cache: $${(this.metrics.cacheHits * 0.0001).toFixed(4)}`);
if (this.metrics.errors.length > 0) {
console.log(`\n⚠️ Errors (${this.metrics.errors.length}):`);
this.metrics.errors.slice(0, 5).forEach((err, i) => {
console.log(` ${i + 1}. ${err.error}`);
});
if (this.metrics.errors.length > 5) {
console.log(` ... and ${this.metrics.errors.length - 5} more`);
}
}
console.log('\n' + '='.repeat(70) + '\n');
}
// Get metrics
getMetrics() {
return { ...this.metrics };
}
}
exports.ProductionPipeline = ProductionPipeline;
// Example quality validator
class ProductQualityValidator {
validate(data) {
const issues = [];
let score = 1.0;
if (!Array.isArray(data) || data.length === 0) {
return { valid: false, score: 0, issues: ['No data generated'] };
}
data.forEach((item, idx) => {
if (!item.description || item.description.length < 50) {
issues.push(`Item ${idx}: Description too short`);
score -= 0.1;
}
if (!item.key_features || !Array.isArray(item.key_features) || item.key_features.length < 3) {
issues.push(`Item ${idx}: Insufficient features`);
score -= 0.1;
}
});
score = Math.max(0, score);
const valid = score >= 0.7;
return { valid, score, issues };
}
}
exports.ProductQualityValidator = ProductQualityValidator;
// Main execution
async function runProductionPipeline() {
const pipeline = new ProductionPipeline({
maxRetries: 3,
retryDelay: 2000,
batchSize: 5,
maxConcurrency: 2,
qualityThreshold: 0.7,
costBudget: 1.0,
rateLimitPerMinute: 30,
enableCaching: true,
outputDirectory: (0, path_1.join)(process.cwd(), 'examples', 'output', 'production')
});
const validator = new ProductQualityValidator();
// Generate product data for e-commerce catalog
const requests = [
{
count: 2,
schema: {
id: { type: 'string', required: true },
name: { type: 'string', required: true },
description: { type: 'string', required: true },
key_features: { type: 'array', items: { type: 'string' }, required: true },
price: { type: 'number', required: true, minimum: 10, maximum: 1000 },
category: { type: 'string', enum: ['Electronics', 'Clothing', 'Home', 'Sports'] }
}
}
];
// Duplicate requests to test batching
const allRequests = Array(5).fill(null).map(() => requests[0]);
const results = await pipeline.run(allRequests, validator);
console.log(`\n✅ Pipeline complete! Generated ${results.length} batches of products.\n`);
}
// Run the example
if (import.meta.url === `file://${process.argv[1]}`) {
runProductionPipeline().catch(error => {
console.error('❌ Pipeline failed:', error);
process.exit(1);
});
}
//# sourceMappingURL=production-pipeline.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,444 @@
/**
* ADVANCED TUTORIAL: Production Pipeline
*
* Build a complete production-ready data generation pipeline with:
* - Error handling and retry logic
* - Monitoring and metrics
* - Rate limiting and cost controls
* - Batch processing and caching
* - Quality validation
*
* What you'll learn:
* - Production-grade error handling
* - Performance monitoring
* - Cost optimization
* - Scalability patterns
* - Deployment best practices
*
* Prerequisites:
* - Complete previous tutorials
* - Set GEMINI_API_KEY environment variable
* - npm install @ruvector/agentic-synth
*
* Run: npx tsx examples/advanced/production-pipeline.ts
*/
import { AgenticSynth, GenerationResult } from '@ruvector/agentic-synth';
import { writeFileSync, existsSync, mkdirSync } from 'fs';
import { join } from 'path';
// Pipeline configuration
interface PipelineConfig {
maxRetries: number;
retryDelay: number;
batchSize: number;
maxConcurrency: number;
qualityThreshold: number;
costBudget: number;
rateLimitPerMinute: number;
enableCaching: boolean;
outputDirectory: string;
}
// Metrics tracking
interface PipelineMetrics {
totalRequests: number;
successfulRequests: number;
failedRequests: number;
totalDuration: number;
totalCost: number;
averageQuality: number;
cacheHits: number;
retries: number;
errors: Array<{ timestamp: Date; error: string; context: any }>;
}
// Quality validator
interface QualityValidator {
validate(data: any): { valid: boolean; score: number; issues: string[] };
}
// Production-grade pipeline
class ProductionPipeline {
private config: PipelineConfig;
private synth: AgenticSynth;
private metrics: PipelineMetrics;
private requestsThisMinute: number = 0;
private minuteStartTime: number = Date.now();
constructor(config: Partial<PipelineConfig> = {}) {
this.config = {
maxRetries: config.maxRetries || 3,
retryDelay: config.retryDelay || 1000,
batchSize: config.batchSize || 10,
maxConcurrency: config.maxConcurrency || 3,
qualityThreshold: config.qualityThreshold || 0.7,
costBudget: config.costBudget || 10.0,
rateLimitPerMinute: config.rateLimitPerMinute || 60,
enableCaching: config.enableCaching !== false,
outputDirectory: config.outputDirectory || './output'
};
this.synth = new AgenticSynth({
provider: 'gemini',
apiKey: process.env.GEMINI_API_KEY,
model: 'gemini-2.0-flash-exp',
cacheStrategy: this.config.enableCaching ? 'memory' : 'none',
cacheTTL: 3600,
maxRetries: this.config.maxRetries,
timeout: 30000
});
this.metrics = {
totalRequests: 0,
successfulRequests: 0,
failedRequests: 0,
totalDuration: 0,
totalCost: 0,
averageQuality: 0,
cacheHits: 0,
retries: 0,
errors: []
};
// Ensure output directory exists
if (!existsSync(this.config.outputDirectory)) {
mkdirSync(this.config.outputDirectory, { recursive: true });
}
}
// Rate limiting check
private async checkRateLimit(): Promise<void> {
const now = Date.now();
const elapsedMinutes = (now - this.minuteStartTime) / 60000;
if (elapsedMinutes >= 1) {
// Reset counter for new minute
this.requestsThisMinute = 0;
this.minuteStartTime = now;
}
if (this.requestsThisMinute >= this.config.rateLimitPerMinute) {
const waitTime = 60000 - (now - this.minuteStartTime);
console.log(`⏳ Rate limit reached, waiting ${Math.ceil(waitTime / 1000)}s...`);
await new Promise(resolve => setTimeout(resolve, waitTime));
this.requestsThisMinute = 0;
this.minuteStartTime = Date.now();
}
}
// Cost check
private checkCostBudget(): void {
if (this.metrics.totalCost >= this.config.costBudget) {
throw new Error(`Cost budget exceeded: $${this.metrics.totalCost.toFixed(4)} >= $${this.config.costBudget}`);
}
}
// Generate with retry logic
private async generateWithRetry(
options: any,
attempt: number = 1
): Promise<GenerationResult> {
try {
await this.checkRateLimit();
this.checkCostBudget();
this.requestsThisMinute++;
this.metrics.totalRequests++;
const startTime = Date.now();
const result = await this.synth.generateStructured(options);
const duration = Date.now() - startTime;
this.metrics.totalDuration += duration;
this.metrics.successfulRequests++;
if (result.metadata.cached) {
this.metrics.cacheHits++;
}
// Estimate cost (rough approximation)
const estimatedCost = result.metadata.cached ? 0 : 0.0001;
this.metrics.totalCost += estimatedCost;
return result;
} catch (error) {
const errorMsg = error instanceof Error ? error.message : 'Unknown error';
if (attempt < this.config.maxRetries) {
this.metrics.retries++;
console.log(`⚠️ Attempt ${attempt} failed, retrying... (${errorMsg})`);
await new Promise(resolve =>
setTimeout(resolve, this.config.retryDelay * attempt)
);
return this.generateWithRetry(options, attempt + 1);
} else {
this.metrics.failedRequests++;
this.metrics.errors.push({
timestamp: new Date(),
error: errorMsg,
context: options
});
throw error;
}
}
}
// Process a single batch
private async processBatch(
requests: any[],
validator?: QualityValidator
): Promise<GenerationResult[]> {
const results: GenerationResult[] = [];
// Process with concurrency control
for (let i = 0; i < requests.length; i += this.config.maxConcurrency) {
const batch = requests.slice(i, i + this.config.maxConcurrency);
const batchResults = await Promise.allSettled(
batch.map(req => this.generateWithRetry(req))
);
batchResults.forEach((result, idx) => {
if (result.status === 'fulfilled') {
const genResult = result.value;
// Validate quality if validator provided
if (validator) {
const validation = validator.validate(genResult.data);
if (validation.valid) {
results.push(genResult);
} else {
console.log(`⚠️ Quality validation failed (score: ${validation.score.toFixed(2)})`);
console.log(` Issues: ${validation.issues.join(', ')}`);
}
} else {
results.push(genResult);
}
} else {
console.error(`❌ Batch item ${i + idx} failed:`, result.reason);
}
});
}
return results;
}
// Main pipeline execution
async run(
requests: any[],
validator?: QualityValidator
): Promise<GenerationResult[]> {
console.log('🏭 Starting Production Pipeline\n');
console.log('=' .repeat(70));
console.log(`\nConfiguration:`);
console.log(` Total Requests: ${requests.length}`);
console.log(` Batch Size: ${this.config.batchSize}`);
console.log(` Max Concurrency: ${this.config.maxConcurrency}`);
console.log(` Max Retries: ${this.config.maxRetries}`);
console.log(` Cost Budget: $${this.config.costBudget}`);
console.log(` Rate Limit: ${this.config.rateLimitPerMinute}/min`);
console.log(` Caching: ${this.config.enableCaching ? 'Enabled' : 'Disabled'}`);
console.log(` Output: ${this.config.outputDirectory}`);
console.log('\n' + '=' .repeat(70) + '\n');
const startTime = Date.now();
const allResults: GenerationResult[] = [];
// Split into batches
const batches = [];
for (let i = 0; i < requests.length; i += this.config.batchSize) {
batches.push(requests.slice(i, i + this.config.batchSize));
}
console.log(`📦 Processing ${batches.length} batches...\n`);
// Process each batch
for (let i = 0; i < batches.length; i++) {
console.log(`\nBatch ${i + 1}/${batches.length} (${batches[i].length} items)`);
console.log('─'.repeat(70));
try {
const batchResults = await this.processBatch(batches[i], validator);
allResults.push(...batchResults);
console.log(`✓ Batch complete: ${batchResults.length}/${batches[i].length} successful`);
console.log(` Cost so far: $${this.metrics.totalCost.toFixed(4)}`);
console.log(` Cache hits: ${this.metrics.cacheHits}`);
} catch (error) {
console.error(`✗ Batch failed:`, error instanceof Error ? error.message : 'Unknown error');
if (error instanceof Error && error.message.includes('budget')) {
console.log('\n⚠ Cost budget exceeded, stopping pipeline...');
break;
}
}
}
const totalTime = Date.now() - startTime;
// Save results
await this.saveResults(allResults);
// Display metrics
this.displayMetrics(totalTime);
return allResults;
}
// Save results to disk
private async saveResults(results: GenerationResult[]): Promise<void> {
try {
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const filename = `generation-${timestamp}.json`;
const filepath = join(this.config.outputDirectory, filename);
const output = {
timestamp: new Date(),
results: results.map(r => r.data),
metadata: {
count: results.length,
metrics: this.metrics
}
};
writeFileSync(filepath, JSON.stringify(output, null, 2));
console.log(`\n💾 Results saved to: ${filepath}`);
// Save metrics separately
const metricsFile = join(this.config.outputDirectory, `metrics-${timestamp}.json`);
writeFileSync(metricsFile, JSON.stringify(this.metrics, null, 2));
console.log(`📊 Metrics saved to: ${metricsFile}`);
} catch (error) {
console.error('⚠️ Failed to save results:', error instanceof Error ? error.message : 'Unknown error');
}
}
// Display comprehensive metrics
private displayMetrics(totalTime: number): void {
console.log('\n\n' + '=' .repeat(70));
console.log('\n📊 PIPELINE METRICS\n');
const successRate = (this.metrics.successfulRequests / this.metrics.totalRequests) * 100;
const avgDuration = this.metrics.totalDuration / this.metrics.successfulRequests;
const cacheHitRate = (this.metrics.cacheHits / this.metrics.totalRequests) * 100;
console.log('Performance:');
console.log(` Total Time: ${(totalTime / 1000).toFixed(2)}s`);
console.log(` Avg Request Time: ${avgDuration.toFixed(0)}ms`);
console.log(` Throughput: ${(this.metrics.successfulRequests / (totalTime / 1000)).toFixed(2)} req/s`);
console.log('\nReliability:');
console.log(` Total Requests: ${this.metrics.totalRequests}`);
console.log(` Successful: ${this.metrics.successfulRequests} (${successRate.toFixed(1)}%)`);
console.log(` Failed: ${this.metrics.failedRequests}`);
console.log(` Retries: ${this.metrics.retries}`);
console.log('\nCost & Efficiency:');
console.log(` Total Cost: $${this.metrics.totalCost.toFixed(4)}`);
console.log(` Avg Cost/Request: $${(this.metrics.totalCost / this.metrics.totalRequests).toFixed(6)}`);
console.log(` Cache Hit Rate: ${cacheHitRate.toFixed(1)}%`);
console.log(` Cost Savings from Cache: $${(this.metrics.cacheHits * 0.0001).toFixed(4)}`);
if (this.metrics.errors.length > 0) {
console.log(`\n⚠ Errors (${this.metrics.errors.length}):`);
this.metrics.errors.slice(0, 5).forEach((err, i) => {
console.log(` ${i + 1}. ${err.error}`);
});
if (this.metrics.errors.length > 5) {
console.log(` ... and ${this.metrics.errors.length - 5} more`);
}
}
console.log('\n' + '=' .repeat(70) + '\n');
}
// Get metrics
getMetrics(): PipelineMetrics {
return { ...this.metrics };
}
}
// Example quality validator
class ProductQualityValidator implements QualityValidator {
validate(data: any[]): { valid: boolean; score: number; issues: string[] } {
const issues: string[] = [];
let score = 1.0;
if (!Array.isArray(data) || data.length === 0) {
return { valid: false, score: 0, issues: ['No data generated'] };
}
data.forEach((item, idx) => {
if (!item.description || item.description.length < 50) {
issues.push(`Item ${idx}: Description too short`);
score -= 0.1;
}
if (!item.key_features || !Array.isArray(item.key_features) || item.key_features.length < 3) {
issues.push(`Item ${idx}: Insufficient features`);
score -= 0.1;
}
});
score = Math.max(0, score);
const valid = score >= 0.7;
return { valid, score, issues };
}
}
// Main execution
async function runProductionPipeline() {
const pipeline = new ProductionPipeline({
maxRetries: 3,
retryDelay: 2000,
batchSize: 5,
maxConcurrency: 2,
qualityThreshold: 0.7,
costBudget: 1.0,
rateLimitPerMinute: 30,
enableCaching: true,
outputDirectory: join(process.cwd(), 'examples', 'output', 'production')
});
const validator = new ProductQualityValidator();
// Generate product data for e-commerce catalog
const requests = [
{
count: 2,
schema: {
id: { type: 'string', required: true },
name: { type: 'string', required: true },
description: { type: 'string', required: true },
key_features: { type: 'array', items: { type: 'string' }, required: true },
price: { type: 'number', required: true, minimum: 10, maximum: 1000 },
category: { type: 'string', enum: ['Electronics', 'Clothing', 'Home', 'Sports'] }
}
}
];
// Duplicate requests to test batching
const allRequests = Array(5).fill(null).map(() => requests[0]);
const results = await pipeline.run(allRequests, validator);
console.log(`\n✅ Pipeline complete! Generated ${results.length} batches of products.\n`);
}
// Run the example
if (import.meta.url === `file://${process.argv[1]}`) {
runProductionPipeline().catch(error => {
console.error('❌ Pipeline failed:', error);
process.exit(1);
});
}
export { ProductionPipeline, ProductQualityValidator, PipelineConfig, PipelineMetrics };