UNPKG

prompt-version-manager

Version:

Centralized prompt management system for Human Behavior AI agents

344 lines 12.9 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.VisualizationDashboard = void 0; const blessed = __importStar(require("blessed")); const versioning_1 = require("../core/versioning"); const manager_1 = require("../chains/manager"); const tracker_1 = require("../chains/tracker"); const contrib = __importStar(require("blessed-contrib")); class VisualizationDashboard { screen; grid; versioning; chainManager; chainTracker; refreshInterval; intervalId; // Dashboard widgets costChart; tokenChart; providerChart; chainFlow; commitLog; diffView; metricsTable; statusBar; constructor(options) { this.versioning = new versioning_1.VersioningOperations(options.repoPath); this.chainManager = new manager_1.ChainManager(options.repoPath); this.chainTracker = new tracker_1.ChainTracker(options.repoPath); this.refreshInterval = options.refreshInterval || 5000; // Initialize blessed screen this.screen = blessed.screen({ smartCSR: true, title: 'PVM Visualization Dashboard', fullUnicode: true }); // Create grid layout this.grid = new contrib.grid({ rows: 12, cols: 12, screen: this.screen }); this.setupWidgets(); this.setupKeyBindings(); } setupWidgets() { // Cost Chart (Top Left) - 4x6 this.costChart = this.grid.set(0, 0, 4, 6, contrib.line, { style: { line: 'yellow', text: 'green', baseline: 'black' }, label: '💰 Cost Analysis Over Time', showLegend: true, legend: { width: 20 } }); // Token Usage Chart (Top Right) - 4x6 this.tokenChart = this.grid.set(0, 6, 4, 6, contrib.bar, { label: '📊 Token Usage by Provider', barWidth: 6, barSpacing: 2, xOffset: 2, maxHeight: 100 }); // Provider Performance Donut (Middle Left) - 4x4 this.providerChart = this.grid.set(4, 0, 4, 4, contrib.donut, { label: '🎯 Provider Distribution', radius: 10, arcWidth: 3, remainColor: 'black', yPadding: 2 }); // Chain Flow Visualization (Middle Center) - 4x8 this.chainFlow = this.grid.set(4, 4, 4, 8, blessed.box, { label: '🔗 Chain Flow Visualization', scrollable: true, alwaysScroll: true, mouse: true, keys: true, vi: true, style: { fg: 'white', border: { fg: 'cyan' } } }); // Commit Log (Bottom Left) - 4x6 this.commitLog = this.grid.set(8, 0, 4, 6, blessed.list, { label: '📝 Commit History', mouse: true, keys: true, vi: true, style: { fg: 'white', selected: { bg: 'blue', fg: 'white' }, border: { fg: 'green' } } }); // Diff View (Bottom Right) - 4x6 this.diffView = this.grid.set(8, 6, 4, 6, blessed.box, { label: '🔍 Commit Diff View', scrollable: true, alwaysScroll: true, mouse: true, keys: true, vi: true, style: { fg: 'white', border: { fg: 'magenta' } } }); // Metrics Table (Status bar at bottom) this.statusBar = blessed.box({ bottom: 0, left: 0, width: '100%', height: 1, style: { fg: 'white', bg: 'blue' }, content: ' Loading dashboard... Press q to quit, r to refresh, arrow keys to navigate ' }); this.screen.append(this.statusBar); } setupKeyBindings() { this.screen.key(['q', 'C-c'], () => { this.stop(); process.exit(0); }); this.screen.key(['r'], () => { this.refresh(); }); this.commitLog.on('select', (item, index) => { this.showCommitDiff(index); }); } async start() { await this.versioning.init(); await this.refresh(); // Start auto-refresh this.intervalId = setInterval(() => { this.refresh().catch(console.error); }, this.refreshInterval); this.screen.render(); } stop() { if (this.intervalId) { clearInterval(this.intervalId); } } async refresh() { try { await this.updateCostChart(); await this.updateTokenChart(); await this.updateProviderChart(); await this.updateChainFlow(); await this.updateCommitLog(); this.statusBar.setContent(` Last updated: ${new Date().toLocaleTimeString()} | Press q to quit, r to refresh `); this.screen.render(); } catch (error) { this.statusBar.setContent(` Error: ${error} `); this.screen.render(); } } async updateCostChart() { // Get historical metrics from chain tracker const metrics = await this.getHistoricalMetrics(); const data = { title: 'Cost Over Time', x: metrics.map((_, i) => i.toString()), y: metrics.map(m => m.totalCost * 100), // Convert to cents for better visualization style: { line: 'yellow' } }; this.costChart.setData([data]); } async updateTokenChart() { const latestMetrics = await this.getLatestMetrics(); if (!latestMetrics) return; const providers = Object.keys(latestMetrics.providerBreakdown); const data = providers.map(provider => latestMetrics.providerBreakdown[provider].tokens.total); this.tokenChart.setData({ titles: providers, data: data }); } async updateProviderChart() { const latestMetrics = await this.getLatestMetrics(); if (!latestMetrics) return; const data = []; let colorIndex = 0; const colors = ['yellow', 'cyan', 'green', 'magenta', 'red']; for (const [provider, stats] of Object.entries(latestMetrics.providerBreakdown)) { data.push({ percent: Math.round((stats.requests / latestMetrics.totalSteps) * 100), label: provider, color: colors[colorIndex++ % colors.length] }); } this.providerChart.setData(data); } async updateChainFlow() { const chains = await this.chainManager.listChains(); if (chains.length === 0) { this.chainFlow.setContent('No chains found'); return; } const latestChain = chains[chains.length - 1]; const nodes = await this.chainManager.getChainNodes(latestChain.id); let flowContent = ''; let indent = 0; for (const node of nodes) { const status = node.status === 'completed' ? '✅' : node.status === 'failed' ? '❌' : '🔄'; flowContent += `${' '.repeat(indent)}${status} ${node.name || node.id}\n`; flowContent += `${' '.repeat(indent)} └─ Model: ${node.model}\n`; flowContent += `${' '.repeat(indent)} └─ Tokens: ${node.metrics?.tokens.total || 0}\n`; flowContent += `${' '.repeat(indent)} └─ Duration: ${node.metrics?.latency || 0}ms\n\n`; if (node.children && node.children.length > 0) { indent++; } } this.chainFlow.setContent(flowContent); } async updateCommitLog() { const commits = await this.versioning.log({ limit: 20 }); const items = commits.map(commit => `${commit.hash.substring(0, 8)} - ${commit.message} (${new Date(commit.timestamp).toLocaleString()})`); this.commitLog.setItems(items); } async showCommitDiff(index) { const commits = await this.versioning.log({ limit: 20 }); if (index >= commits.length) return; const commit = commits[index]; // Get diff between this commit and its parent let diffContent = `Commit: ${commit.hash}\n`; diffContent += `Author: ${commit.author}\n`; diffContent += `Date: ${new Date(commit.timestamp).toLocaleString()}\n`; diffContent += `Message: ${commit.message}\n\n`; if (commit.parent) { try { const parentCommit = await this.versioning.storage.getObject(commit.parent); const currentPrompt = await this.versioning.storage.getObject(commit.prompt); diffContent += '=== Prompt Changes ===\n'; diffContent += this.generateDiff(JSON.stringify(parentCommit, null, 2), JSON.stringify(currentPrompt, null, 2)); } catch (error) { diffContent += 'Unable to generate diff'; } } else { diffContent += 'Initial commit - no parent to compare'; } this.diffView.setContent(diffContent); this.screen.render(); } generateDiff(oldContent, newContent) { const oldLines = oldContent.split('\n'); const newLines = newContent.split('\n'); let diff = ''; // Simple line-by-line diff const maxLines = Math.max(oldLines.length, newLines.length); for (let i = 0; i < maxLines; i++) { if (i >= oldLines.length) { diff += `{green-fg}+ ${newLines[i]}{/green-fg}\n`; } else if (i >= newLines.length) { diff += `{red-fg}- ${oldLines[i]}{/red-fg}\n`; } else if (oldLines[i] !== newLines[i]) { diff += `{red-fg}- ${oldLines[i]}{/red-fg}\n`; diff += `{green-fg}+ ${newLines[i]}{/green-fg}\n`; } } return diff; } async getHistoricalMetrics() { // In a real implementation, this would fetch from a metrics store // For now, generate sample data const metrics = []; for (let i = 0; i < 10; i++) { metrics.push({ chainId: `chain-${i}`, totalSteps: 5, successfulSteps: Math.floor(Math.random() * 5) + 1, failedSteps: 0, totalTokens: { input: Math.floor(Math.random() * 1000) + 500, output: Math.floor(Math.random() * 1000) + 500, total: Math.floor(Math.random() * 2000) + 1000 }, totalCost: Math.random() * 0.5, totalDuration: Math.floor(Math.random() * 60000) + 30000, providerBreakdown: {} }); } return metrics; } async getLatestMetrics() { const metrics = await this.getHistoricalMetrics(); return metrics[metrics.length - 1] || null; } } exports.VisualizationDashboard = VisualizationDashboard; // CLI entry point if (require.main === module) { const dashboard = new VisualizationDashboard({ repoPath: process.env.PVM_REPO_PATH || './pvm-data' }); dashboard.start().catch(console.error); } //# sourceMappingURL=dashboard.js.map