This is page 14 of 18. Use http://codebase.md/minipuft/claude-prompts-mcp?lines=true&page={x} to view the full context. # Directory Structure ``` ├── .actrc ├── .gitattributes ├── .github │ └── workflows │ ├── ci.yml │ ├── mcp-compliance.yml │ └── pr-validation.yml ├── .gitignore ├── agent.md ├── assets │ └── logo.png ├── CLAUDE.md ├── config │ └── framework-state.json ├── docs │ ├── architecture.md │ ├── chain-modification-examples.md │ ├── contributing.md │ ├── enhanced-gate-system.md │ ├── execution-architecture-guide.md │ ├── installation-guide.md │ ├── mcp-tool-usage-guide.md │ ├── mcp-tools-reference.md │ ├── prompt-format-guide.md │ ├── prompt-management.md │ ├── prompt-vs-template-guide.md │ ├── README.md │ ├── template-development-guide.md │ ├── TODO.md │ ├── troubleshooting.md │ └── version-history.md ├── LICENSE ├── local-test.sh ├── plans │ ├── nunjucks-dynamic-chain-orchestration.md │ ├── outputschema-realtime-progress-and-validation.md │ ├── parallel-conditional-execution-analysis.md │ ├── sqlite-storage-migration.md │ └── symbolic-command-language-implementation.md ├── README.md ├── scripts │ ├── setup-windows-testing.sh │ ├── test_server.js │ ├── test-all-platforms.sh │ └── windows-tests │ ├── test-windows-paths.js │ ├── test-windows-startup.sh │ └── windows-env.sh └── server ├── config │ ├── framework-state.json │ └── tool-descriptions.json ├── config.json ├── jest.config.cjs ├── LICENSE ├── package-lock.json ├── package.json ├── prompts │ ├── analysis │ │ ├── advanced_analysis_engine.md │ │ ├── content_analysis.md │ │ ├── deep_analysis.md │ │ ├── deep_research.md │ │ ├── markdown_notebook.md │ │ ├── note_integration.md │ │ ├── note_refinement.md │ │ ├── notes.md │ │ ├── progressive_research.md │ │ ├── prompts.json │ │ ├── query_refinement.md │ │ └── review.md │ ├── architecture │ │ ├── prompts.json │ │ └── strategic-system-alignment.md │ ├── content_processing │ │ ├── format_enhancement.md │ │ ├── noteIntegration.md │ │ ├── obsidian_metadata_optimizer.md │ │ ├── prompts.json │ │ ├── vault_related_notes_finder.md │ │ └── video_notes_enhanced.md │ ├── debugging │ │ ├── analyze_logs.md │ │ └── prompts.json │ ├── development │ │ ├── analyze_code_structure.md │ │ ├── analyze_file_structure.md │ │ ├── code_review_optimization_chain.md │ │ ├── component_flow_analysis.md │ │ ├── create_modularization_plan.md │ │ ├── detect_code_issues.md │ │ ├── detect_project_commands.md │ │ ├── expert_code_implementation.md │ │ ├── generate_comprehensive_claude_md.md │ │ ├── prompts.json │ │ ├── strategicImplement.md │ │ ├── suggest_code_improvements.md │ │ └── transform_code_to_modules.md │ ├── documentation │ │ ├── create_docs_chain.md │ │ ├── docs-content-creation.md │ │ ├── docs-content-planning.md │ │ ├── docs-final-assembly.md │ │ ├── docs-project-analysis.md │ │ ├── docs-review-refinement.md │ │ └── prompts.json │ ├── education │ │ ├── prompts.json │ │ └── vault_integrated_notes.md │ ├── general │ │ ├── diagnose.md │ │ └── prompts.json │ ├── promptsConfig.json │ └── testing │ ├── final_verification_test.md │ └── prompts.json ├── README.md ├── scripts │ └── validate-dependencies.js ├── src │ ├── api │ │ └── index.ts │ ├── chain-session │ │ └── manager.ts │ ├── config │ │ └── index.ts │ ├── Dockerfile │ ├── execution │ │ ├── context │ │ │ ├── context-resolver.ts │ │ │ ├── framework-injector.ts │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── parsers │ │ │ ├── argument-parser.ts │ │ │ ├── index.ts │ │ │ └── unified-command-parser.ts │ │ └── types.ts │ ├── frameworks │ │ ├── framework-manager.ts │ │ ├── framework-state-manager.ts │ │ ├── index.ts │ │ ├── integration │ │ │ ├── framework-semantic-integration.ts │ │ │ └── index.ts │ │ ├── methodology │ │ │ ├── guides │ │ │ │ ├── 5w1h-guide.ts │ │ │ │ ├── cageerf-guide.ts │ │ │ │ ├── react-guide.ts │ │ │ │ └── scamper-guide.ts │ │ │ ├── index.ts │ │ │ ├── interfaces.ts │ │ │ └── registry.ts │ │ ├── prompt-guidance │ │ │ ├── index.ts │ │ │ ├── methodology-tracker.ts │ │ │ ├── service.ts │ │ │ ├── system-prompt-injector.ts │ │ │ └── template-enhancer.ts │ │ └── types │ │ ├── index.ts │ │ ├── integration-types.ts │ │ ├── methodology-types.ts │ │ └── prompt-guidance-types.ts │ ├── gates │ │ ├── constants.ts │ │ ├── core │ │ │ ├── gate-definitions.ts │ │ │ ├── gate-loader.ts │ │ │ ├── gate-validator.ts │ │ │ ├── index.ts │ │ │ └── temporary-gate-registry.ts │ │ ├── definitions │ │ │ ├── code-quality.json │ │ │ ├── content-structure.json │ │ │ ├── educational-clarity.json │ │ │ ├── framework-compliance.json │ │ │ ├── research-quality.json │ │ │ ├── security-awareness.json │ │ │ └── technical-accuracy.json │ │ ├── gate-state-manager.ts │ │ ├── guidance │ │ │ ├── FrameworkGuidanceFilter.ts │ │ │ └── GateGuidanceRenderer.ts │ │ ├── index.ts │ │ ├── intelligence │ │ │ ├── GatePerformanceAnalyzer.ts │ │ │ └── GateSelectionEngine.ts │ │ ├── templates │ │ │ ├── code_quality_validation.md │ │ │ ├── educational_clarity_validation.md │ │ │ ├── framework_compliance_validation.md │ │ │ ├── research_self_validation.md │ │ │ ├── security_validation.md │ │ │ ├── structure_validation.md │ │ │ └── technical_accuracy_validation.md │ │ └── types.ts │ ├── index.ts │ ├── logging │ │ └── index.ts │ ├── mcp-tools │ │ ├── config-utils.ts │ │ ├── constants.ts │ │ ├── index.ts │ │ ├── prompt-engine │ │ │ ├── core │ │ │ │ ├── engine.ts │ │ │ │ ├── executor.ts │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── index.ts │ │ │ ├── processors │ │ │ │ ├── response-formatter.ts │ │ │ │ └── template-processor.ts │ │ │ └── utils │ │ │ ├── category-extractor.ts │ │ │ ├── classification.ts │ │ │ ├── context-builder.ts │ │ │ └── validation.ts │ │ ├── prompt-manager │ │ │ ├── analysis │ │ │ │ ├── comparison-engine.ts │ │ │ │ ├── gate-analyzer.ts │ │ │ │ └── prompt-analyzer.ts │ │ │ ├── core │ │ │ │ ├── index.ts │ │ │ │ ├── manager.ts │ │ │ │ └── types.ts │ │ │ ├── index.ts │ │ │ ├── operations │ │ │ │ └── file-operations.ts │ │ │ ├── search │ │ │ │ ├── filter-parser.ts │ │ │ │ └── prompt-matcher.ts │ │ │ └── utils │ │ │ ├── category-manager.ts │ │ │ └── validation.ts │ │ ├── shared │ │ │ └── structured-response-builder.ts │ │ ├── system-control.ts │ │ ├── tool-description-manager.ts │ │ └── types │ │ └── shared-types.ts │ ├── metrics │ │ ├── analytics-service.ts │ │ ├── index.ts │ │ └── types.ts │ ├── performance │ │ ├── index.ts │ │ └── monitor.ts │ ├── prompts │ │ ├── category-manager.ts │ │ ├── converter.ts │ │ ├── file-observer.ts │ │ ├── hot-reload-manager.ts │ │ ├── index.ts │ │ ├── loader.ts │ │ ├── promptUtils.ts │ │ ├── registry.ts │ │ └── types.ts │ ├── runtime │ │ ├── application.ts │ │ └── startup.ts │ ├── semantic │ │ ├── configurable-semantic-analyzer.ts │ │ └── integrations │ │ ├── index.ts │ │ └── llm-clients.ts │ ├── server │ │ ├── index.ts │ │ └── transport │ │ └── index.ts │ ├── smithery.yaml │ ├── text-references │ │ ├── conversation.ts │ │ └── index.ts │ ├── types │ │ └── index.ts │ ├── types.ts │ └── utils │ ├── chainUtils.ts │ ├── errorHandling.ts │ ├── global-resource-tracker.ts │ ├── index.ts │ └── jsonUtils.ts ├── tests │ ├── ci-startup-validation.js │ ├── enhanced-validation │ │ ├── contract-validation │ │ │ ├── contract-test-suite.js │ │ │ ├── interface-contracts.js │ │ │ └── interface-contracts.ts │ │ ├── environment-validation │ │ │ ├── environment-parity-checker.js │ │ │ └── environment-test-suite.js │ │ ├── lifecycle-validation │ │ │ ├── lifecycle-test-suite.js │ │ │ └── process-lifecycle-validator.js │ │ └── validation-orchestrator.js │ ├── helpers │ │ └── test-helpers.js │ ├── integration │ │ ├── mcp-tools.test.ts │ │ ├── server-startup.test.ts │ │ └── unified-parsing-integration.test.ts │ ├── performance │ │ ├── parsing-system-benchmark.test.ts │ │ └── server-performance.test.ts │ ├── scripts │ │ ├── consolidated-tools.js │ │ ├── establish-performance-baselines.js │ │ ├── functional-mcp-validation.js │ │ ├── integration-mcp-tools.js │ │ ├── integration-routing-system.js │ │ ├── integration-server-startup.js │ │ ├── integration-unified-parsing.js │ │ ├── methodology-guides.js │ │ ├── performance-memory.js │ │ ├── runtime-integration.js │ │ ├── unit-conversation-manager.js │ │ ├── unit-semantic-analyzer.js │ │ └── unit-unified-parsing.js │ ├── setup.ts │ ├── test-enhanced-parsing.js │ └── unit │ ├── conversation-manager.test.ts │ ├── semantic-analyzer-three-tier.test.ts │ └── unified-parsing-system.test.ts ├── tsconfig.json └── tsconfig.test.json ``` # Files -------------------------------------------------------------------------------- /server/src/mcp-tools/prompt-manager/core/manager.ts: -------------------------------------------------------------------------------- ```typescript 1 | /** 2 | * Consolidated Prompt Manager - Modular Architecture Orchestration Layer 3 | * 4 | * This class maintains 100% backwards compatibility with the original API 5 | * while delegating operations to specialized modules for improved maintainability. 6 | */ 7 | 8 | import { Logger } from "../../../logging/index.js"; 9 | import { ConfigManager } from "../../../config/index.js"; 10 | import { 11 | ToolResponse, 12 | ConvertedPrompt, 13 | PromptData, 14 | Category 15 | } from "../../../types/index.js"; 16 | import { 17 | ValidationError, 18 | PromptError, 19 | handleError as utilsHandleError 20 | } from "../../../utils/index.js"; 21 | import { ContentAnalyzer } from "../../../semantic/configurable-semantic-analyzer.js"; 22 | import { FrameworkStateManager } from "../../../frameworks/framework-state-manager.js"; 23 | import { FrameworkManager } from "../../../frameworks/framework-manager.js"; 24 | import { createPromptResponse, createErrorResponse } from "../../shared/structured-response-builder.js"; 25 | 26 | // Modular components 27 | import { 28 | PromptManagerDependencies, 29 | PromptManagerData, 30 | PromptClassification 31 | } from "./types.js"; 32 | import { validateRequiredFields } from "../utils/validation.js"; 33 | import { PromptAnalyzer } from "../analysis/prompt-analyzer.js"; 34 | import { ComparisonEngine } from "../analysis/comparison-engine.js"; 35 | import { GateAnalyzer } from "../analysis/gate-analyzer.js"; 36 | import { FilterParser } from "../search/filter-parser.js"; 37 | import { PromptMatcher } from "../search/prompt-matcher.js"; 38 | import { FileOperations } from "../operations/file-operations.js"; 39 | 40 | /** 41 | * Consolidated Prompt Manager - Modular Architecture 42 | */ 43 | export class ConsolidatedPromptManager { 44 | private logger: Logger; 45 | private mcpServer: any; 46 | private configManager: ConfigManager; 47 | private semanticAnalyzer: ContentAnalyzer; 48 | private frameworkStateManager?: FrameworkStateManager; 49 | private frameworkManager?: FrameworkManager; 50 | private onRefresh: () => Promise<void>; 51 | private onRestart: (reason: string) => Promise<void>; 52 | 53 | // Modular components 54 | private promptAnalyzer: PromptAnalyzer; 55 | private comparisonEngine: ComparisonEngine; 56 | private gateAnalyzer: GateAnalyzer; 57 | private filterParser: FilterParser; 58 | private promptMatcher: PromptMatcher; 59 | private fileOperations: FileOperations; 60 | 61 | // Data references 62 | private promptsData: PromptData[] = []; 63 | private convertedPrompts: ConvertedPrompt[] = []; 64 | private categories: Category[] = []; 65 | 66 | constructor( 67 | logger: Logger, 68 | mcpServer: any, 69 | configManager: ConfigManager, 70 | semanticAnalyzer: ContentAnalyzer, 71 | frameworkStateManager: FrameworkStateManager | undefined, 72 | frameworkManager: FrameworkManager | undefined, 73 | onRefresh: () => Promise<void>, 74 | onRestart: (reason: string) => Promise<void> 75 | ) { 76 | this.logger = logger; 77 | this.mcpServer = mcpServer; 78 | this.configManager = configManager; 79 | this.semanticAnalyzer = semanticAnalyzer; 80 | this.frameworkStateManager = frameworkStateManager; 81 | this.frameworkManager = frameworkManager; 82 | this.onRefresh = onRefresh; 83 | this.onRestart = onRestart; 84 | 85 | // Initialize modular components 86 | const dependencies: PromptManagerDependencies = { 87 | logger, 88 | mcpServer, 89 | configManager, 90 | semanticAnalyzer, 91 | frameworkStateManager, 92 | frameworkManager, 93 | onRefresh, 94 | onRestart 95 | }; 96 | 97 | this.promptAnalyzer = new PromptAnalyzer(dependencies); 98 | this.comparisonEngine = new ComparisonEngine(logger); 99 | this.gateAnalyzer = new GateAnalyzer(dependencies); 100 | this.filterParser = new FilterParser(logger); 101 | this.promptMatcher = new PromptMatcher(logger); 102 | this.fileOperations = new FileOperations(dependencies); 103 | 104 | this.logger.debug("ConsolidatedPromptManager initialized with modular architecture"); 105 | } 106 | 107 | /** 108 | * Update data references 109 | */ 110 | updateData( 111 | promptsData: PromptData[], 112 | convertedPrompts: ConvertedPrompt[], 113 | categories: Category[] 114 | ): void { 115 | this.promptsData = promptsData; 116 | this.convertedPrompts = convertedPrompts; 117 | this.categories = categories; 118 | 119 | // Update modular components that need data references 120 | const data: PromptManagerData = { 121 | promptsData, 122 | convertedPrompts, 123 | categories 124 | }; 125 | 126 | // Components handle their own data updates if needed 127 | this.logger.debug(`Updated data references: ${promptsData.length} prompts, ${categories.length} categories`); 128 | } 129 | 130 | /** 131 | * Set framework state manager (called during initialization) 132 | */ 133 | setFrameworkStateManager(frameworkStateManager: FrameworkStateManager): void { 134 | this.frameworkStateManager = frameworkStateManager; 135 | this.logger.debug("Framework state manager set in PromptManager"); 136 | } 137 | 138 | /** 139 | * Set framework manager (called during initialization) 140 | */ 141 | setFrameworkManager(frameworkManager: FrameworkManager): void { 142 | this.frameworkManager = frameworkManager; 143 | this.logger.debug("Framework manager set in PromptManager"); 144 | } 145 | 146 | /** 147 | * Main action handler - Routes to appropriate modules 148 | */ 149 | public async handleAction(args: { 150 | action: "create" | "create_prompt" | "create_template" | "analyze_type" | "migrate_type" | "update" | "delete" | "modify" | "reload" | "list" | "analyze_gates" | "suggest_temporary_gates" | "create_with_gates" | "update_gates" | "add_temporary_gates"; 151 | [key: string]: any; 152 | }, extra: any): Promise<ToolResponse> { 153 | 154 | const { action } = args; 155 | // USING ERROR LEVEL FOR GUARANTEED VISIBILITY IN LOGS 156 | this.logger.error(`[GATE-TRACE] 🚀 ENTRY POINT: handleAction called with action "${action}"`); 157 | this.logger.error(`[GATE-TRACE] Gate config present: ${!!args.gate_configuration}, Type: ${typeof args.gate_configuration}`); 158 | this.logger.info(`📝 Prompt Manager: Executing action "${action}"`); 159 | 160 | try { 161 | switch (action) { 162 | case "create": 163 | return await this.createPrompt(args); 164 | 165 | case "create_prompt": 166 | return await this.createBasicPrompt(args); 167 | 168 | case "create_template": 169 | return await this.createFrameworkTemplate(args); 170 | 171 | case "analyze_type": 172 | return await this.analyzePromptType(args); 173 | 174 | case "migrate_type": 175 | return await this.migratePromptType(args); 176 | 177 | case "update": 178 | return await this.updatePrompt(args); 179 | 180 | case "delete": 181 | return await this.deletePrompt(args); 182 | 183 | case "modify": 184 | return await this.modifyPrompt(args); 185 | 186 | case "reload": 187 | return await this.reloadPrompts(args); 188 | 189 | case "list": 190 | return await this.listPrompts(args); 191 | 192 | case "analyze_gates": 193 | return await this.analyzePromptGates(args); 194 | 195 | case "suggest_temporary_gates": 196 | return await this.suggestTemporaryGates(args); 197 | 198 | case "create_with_gates": 199 | return await this.createPromptWithGates(args); 200 | 201 | case "update_gates": 202 | return await this.updatePromptGates(args); 203 | 204 | case "add_temporary_gates": 205 | return await this.addTemporaryGates(args); 206 | 207 | default: 208 | throw new ValidationError(`Unknown action: ${action}`); 209 | } 210 | } catch (error) { 211 | return this.handleError(error, action); 212 | } 213 | } 214 | 215 | /** 216 | * Create new prompt (delegates to file operations and analysis) 217 | */ 218 | private async createPrompt(args: any): Promise<ToolResponse> { 219 | validateRequiredFields(args, ['id', 'name', 'description', 'user_message_template']); 220 | 221 | // Create prompt data with enhanced gate configuration support 222 | const promptData: any = { 223 | id: args.id, 224 | name: args.name, 225 | category: args.category || 'general', 226 | description: args.description, 227 | systemMessage: args.system_message, 228 | userMessageTemplate: args.user_message_template, 229 | arguments: args.arguments || [], 230 | isChain: args.is_chain || false, 231 | chainSteps: args.chain_steps || [], 232 | gateConfiguration: args.gate_configuration || args.gates 233 | }; 234 | 235 | // USING ERROR LEVEL FOR GUARANTEED VISIBILITY 236 | this.logger.error(`[GATE-TRACE] 📋 createPrompt constructed promptData for ${args.id}`); 237 | this.logger.error(`[GATE-TRACE] promptData final structure:`, { 238 | id: promptData.id, 239 | hasGateConfiguration: !!promptData.gateConfiguration, 240 | gateConfigType: typeof promptData.gateConfiguration, 241 | gateConfigValue: promptData.gateConfiguration, 242 | argsGateConfig: args.gate_configuration, 243 | argsGates: args.gates 244 | }); 245 | 246 | this.logger.error(`[GATE-TRACE] 📁 Calling fileOperations.updatePromptImplementation for ${args.id}`); 247 | const result = await this.fileOperations.updatePromptImplementation(promptData); 248 | 249 | // Perform intelligent analysis 250 | const analysis = await this.promptAnalyzer.analyzePromptIntelligence(promptData); 251 | 252 | let response = `✅ **Prompt Created**: ${args.name} (${args.id})\n`; 253 | response += `📝 ${args.description}\n`; 254 | response += `${analysis.feedback}`; 255 | 256 | if (analysis.suggestions.length > 0) { 257 | response += `💡 ${analysis.suggestions.join(' • ')}\n`; 258 | } 259 | 260 | // Enhanced: Gate configuration analysis and suggestions 261 | if (promptData.gateConfiguration) { 262 | response += `\n🔒 **Gate Configuration Applied**:\n`; 263 | if (promptData.gateConfiguration.include) { 264 | response += `- Include Gates: ${promptData.gateConfiguration.include.join(', ')}\n`; 265 | } 266 | if (promptData.gateConfiguration.temporary_gates) { 267 | response += `- Temporary Gates: ${promptData.gateConfiguration.temporary_gates.length} defined\n`; 268 | } 269 | } else if (this.semanticAnalyzer.isLLMEnabled()) { 270 | // Suggest gate configuration for prompts without gates (only when API analysis is enabled) 271 | try { 272 | const gateAnalysis = await this.gateAnalyzer.analyzePromptForGates({ 273 | id: promptData.id, 274 | name: promptData.name, 275 | category: promptData.category, 276 | description: promptData.description, 277 | userMessageTemplate: promptData.userMessageTemplate, 278 | systemMessage: promptData.systemMessage, 279 | arguments: promptData.arguments || [] 280 | }); 281 | 282 | if (gateAnalysis.recommendedGates.length > 0) { 283 | response += `\n💡 **Suggested Gates**: Consider adding these gates:\n`; 284 | gateAnalysis.recommendedGates.slice(0, 3).forEach(gate => { 285 | response += `- ${gate}\n`; 286 | }); 287 | response += `Use \`update_gates\` action to add gate configuration.\n`; 288 | } 289 | } catch (error) { 290 | this.logger.warn('Failed to analyze gates for new prompt:', error); 291 | } 292 | } 293 | 294 | await this.handleSystemRefresh(args.full_restart, `Prompt created: ${args.id}`); 295 | 296 | return createPromptResponse(response, "create", { 297 | promptId: args.id, 298 | category: args.category, 299 | analysisResult: analysis, 300 | affectedFiles: [`${args.id}.md`] 301 | }); 302 | } 303 | 304 | /** 305 | * Update existing prompt (delegates to file operations and comparison) 306 | */ 307 | private async updatePrompt(args: any): Promise<ToolResponse> { 308 | validateRequiredFields(args, ['id']); 309 | 310 | // Get current prompt for comparison 311 | const currentPrompt = this.convertedPrompts.find(p => p.id === args.id); 312 | let beforeAnalysis: PromptClassification | null = null; 313 | 314 | if (currentPrompt) { 315 | beforeAnalysis = await this.promptAnalyzer.analyzePrompt(currentPrompt); 316 | } 317 | 318 | // Update prompt data with enhanced gate configuration support 319 | const promptData: any = { 320 | id: args.id, 321 | name: args.name || currentPrompt?.name || args.id, 322 | category: args.category || currentPrompt?.category || 'general', 323 | description: args.description || currentPrompt?.description || '', 324 | systemMessage: args.system_message || currentPrompt?.systemMessage, 325 | userMessageTemplate: args.user_message_template || currentPrompt?.userMessageTemplate || '', 326 | arguments: args.arguments || currentPrompt?.arguments || [], 327 | chainSteps: args.chain_steps || currentPrompt?.chainSteps || [], 328 | gateConfiguration: args.gate_configuration || args.gates || currentPrompt?.gateConfiguration 329 | }; 330 | 331 | const result = await this.fileOperations.updatePromptImplementation(promptData); 332 | 333 | // Perform analysis comparison 334 | const afterAnalysis = await this.promptAnalyzer.analyzePromptIntelligence(promptData); 335 | 336 | let response = `✅ **Prompt Updated**: ${promptData.name} (${args.id})\n\n`; 337 | response += `${result.message}\n\n`; 338 | response += `${afterAnalysis.feedback}\n`; 339 | 340 | // Add comparison if we have before analysis 341 | if (beforeAnalysis) { 342 | const comparison = this.comparisonEngine.compareAnalyses(beforeAnalysis, afterAnalysis.classification, args.id); 343 | const displaySummary = this.comparisonEngine.generateDisplaySummary(comparison); 344 | if (displaySummary) { 345 | response += `\n${displaySummary}\n`; 346 | } 347 | } 348 | 349 | if (afterAnalysis.suggestions.length > 0) { 350 | response += `\n💡 **Improvement Suggestions**:\n`; 351 | afterAnalysis.suggestions.forEach((suggestion, i) => { 352 | response += `${i + 1}. ${suggestion}\n`; 353 | }); 354 | } 355 | 356 | await this.handleSystemRefresh(args.full_restart, `Prompt updated: ${args.id}`); 357 | 358 | return createPromptResponse(response, "update", { 359 | promptId: args.id, 360 | category: promptData.category, 361 | analysisResult: afterAnalysis, 362 | affectedFiles: [`${args.id}.md`] 363 | }); 364 | } 365 | 366 | /** 367 | * Delete prompt with safety checks (delegates to file operations) 368 | */ 369 | private async deletePrompt(args: any): Promise<ToolResponse> { 370 | validateRequiredFields(args, ['id']); 371 | 372 | const promptToDelete = this.promptsData.find(p => p.id === args.id); 373 | if (!promptToDelete) { 374 | throw new PromptError(`Prompt not found: ${args.id}`); 375 | } 376 | 377 | // Safety check - analyze dependencies 378 | const dependencies = this.findPromptDependencies(args.id); 379 | 380 | let response = `🗑️ **Deleting Prompt**: ${promptToDelete.name} (${args.id})\n\n`; 381 | 382 | if (dependencies.length > 0) { 383 | response += `⚠️ **Warning**: This prompt is referenced by ${dependencies.length} other prompts:\n`; 384 | dependencies.forEach(dep => { 385 | response += `- ${dep.name} (${dep.id})\n`; 386 | }); 387 | response += `\nDeleting will break these chain references.\n\n`; 388 | } 389 | 390 | const result = await this.fileOperations.deletePromptImplementation(args.id); 391 | response += `${result.message}\n\n`; 392 | response += `✅ **Prompt successfully removed from system**\n`; 393 | 394 | await this.handleSystemRefresh(args.full_restart, `Prompt deleted: ${args.id}`); 395 | 396 | return createPromptResponse(response, "delete", { 397 | promptId: args.id, 398 | category: promptToDelete.category, 399 | affectedFiles: [`${args.id}.md`] 400 | }); 401 | } 402 | 403 | /** 404 | * List prompts with intelligent filtering (delegates to search modules) 405 | */ 406 | private async listPrompts(args: any): Promise<ToolResponse> { 407 | console.log(`[DEBUG] List prompts called with search_query: "${args.search_query || ''}"`); 408 | const filters = this.filterParser.parseIntelligentFilters(args.search_query || ''); 409 | console.log(`[DEBUG] Parsed filters:`, filters); 410 | const matchingPrompts: Array<{ 411 | prompt: any; 412 | classification: any; 413 | }> = []; 414 | 415 | // Process all prompts using matcher 416 | console.log(`[DEBUG] Processing ${this.convertedPrompts.length} prompts`); 417 | for (const prompt of this.convertedPrompts) { 418 | try { 419 | const classification = await this.promptAnalyzer.analyzePrompt(prompt); 420 | console.log(`[DEBUG] Analyzing prompt ${prompt.id}, type: ${classification.executionType}`); 421 | 422 | // Apply filters using matcher 423 | const matches = await this.promptMatcher.matchesFilters(prompt, filters, classification); 424 | console.log(`[DEBUG] Prompt ${prompt.id} matches: ${matches}`); 425 | if (matches) { 426 | matchingPrompts.push({ prompt, classification }); 427 | } 428 | } catch (error) { 429 | this.logger.warn(`Failed to analyze prompt ${prompt.id}:`, error); 430 | } 431 | } 432 | 433 | // Sort by relevance 434 | matchingPrompts.sort((a, b) => { 435 | const scoreA = this.promptMatcher.calculateRelevanceScore(a.prompt, a.classification, filters); 436 | const scoreB = this.promptMatcher.calculateRelevanceScore(b.prompt, b.classification, filters); 437 | return scoreB - scoreA; // Higher scores first 438 | }); 439 | 440 | if (matchingPrompts.length === 0) { 441 | return createPromptResponse( 442 | `📭 No prompts found matching filter: "${args.search_query || 'all'}"\n\n💡 Try broader search terms or use filters like 'type:template', 'category:analysis'`, 443 | "list", 444 | { 445 | promptId: "none", 446 | category: "all", 447 | affectedFiles: [] 448 | } 449 | ); 450 | } 451 | 452 | // Generate response using existing format 453 | let result = `📚 **Prompt Library** (${matchingPrompts.length} prompts)\n\n`; 454 | 455 | // Group by category for better organization 456 | const groupedByCategory = matchingPrompts.reduce((acc, item) => { 457 | const category = item.prompt.category || 'uncategorized'; 458 | if (!acc[category]) acc[category] = []; 459 | acc[category].push(item); 460 | return acc; 461 | }, {} as Record<string, typeof matchingPrompts>); 462 | 463 | for (const [category, prompts] of Object.entries(groupedByCategory)) { 464 | result += `\n## 📁 ${category.toUpperCase()}\n`; 465 | 466 | for (const { prompt, classification } of prompts) { 467 | const executionIcon = this.getExecutionTypeIcon(classification.executionType); 468 | const frameworkIcon = classification.requiresFramework ? '🧠' : '⚡'; 469 | 470 | result += `\n**${executionIcon} ${prompt.name}** \`${prompt.id}\`\n`; 471 | result += ` ${frameworkIcon} **Type**: ${classification.executionType}\n`; 472 | 473 | if (prompt.description) { 474 | const shortDesc = prompt.description.length > 80 475 | ? prompt.description.substring(0, 80) + '...' 476 | : prompt.description; 477 | result += ` 📝 ${shortDesc}\n`; 478 | } 479 | 480 | if (prompt.arguments?.length > 0) { 481 | result += ` 🔧 **Args**: ${prompt.arguments.map((arg: any) => arg.name).join(', ')}\n`; 482 | } 483 | } 484 | } 485 | 486 | // Add filter summary if filters were applied 487 | if (args.filter) { 488 | const filterDescriptions = this.filterParser.buildFilterDescription(filters); 489 | if (filterDescriptions.length > 0) { 490 | result += `\n\n🔍 **Applied Filters**:\n`; 491 | filterDescriptions.forEach(desc => { 492 | result += `- ${desc}\n`; 493 | }); 494 | } 495 | } 496 | 497 | result += `\n\n💡 **Usage Tips**:\n`; 498 | result += `• Use \`>>prompt_id\` to execute prompts\n`; 499 | result += `• Use \`analyze_type\` to get type recommendations\n`; 500 | result += `• Use \`migrate_type\` to convert between prompt/template\n`; 501 | 502 | return createPromptResponse(result, "list_intelligent", { 503 | promptId: "multiple", 504 | category: "all" 505 | }); 506 | } 507 | 508 | /** 509 | * Analyze prompt type (delegates to analysis module) 510 | */ 511 | private async analyzePromptType(args: any): Promise<ToolResponse> { 512 | validateRequiredFields(args, ['id']); 513 | 514 | const prompt = this.convertedPrompts.find(p => p.id === args.id); 515 | if (!prompt) { 516 | return createErrorResponse(`Prompt not found: ${args.id}`, { 517 | tool: "prompt_manager", 518 | operation: "analyze_type", 519 | errorType: "validation", 520 | severity: "medium" 521 | }); 522 | } 523 | 524 | const analysis = await this.promptAnalyzer.analyzePrompt(prompt); 525 | 526 | let recommendation = `🔍 **Prompt Type Analysis**: ${prompt.name}\n\n`; 527 | recommendation += `📊 **Current Execution Type**: ${analysis.executionType}\n`; 528 | recommendation += `🧠 **Framework Recommended**: ${analysis.requiresFramework ? 'Yes' : 'No'}\n\n`; 529 | 530 | recommendation += `📋 **Analysis Details**:\n`; 531 | analysis.reasoning.forEach((reason, i) => { 532 | recommendation += `${i + 1}. ${reason}\n`; 533 | }); 534 | 535 | recommendation += `\n🔄 **Recommendations**:\n`; 536 | 537 | if (analysis.executionType === 'prompt' && analysis.requiresFramework) { 538 | recommendation += `⬆️ **Consider upgrading to template**: This prompt would benefit from framework guidance\n`; 539 | recommendation += `💡 **Migration**: Use \`migrate_type\` action to convert to template\n`; 540 | } else if (analysis.executionType === 'template' && !analysis.requiresFramework) { 541 | recommendation += `⬇️ **Consider simplifying to prompt**: This might be over-engineered for its use case\n`; 542 | recommendation += `💡 **Migration**: Use \`migrate_type\` action to convert to basic prompt\n`; 543 | } else { 544 | recommendation += `✅ **Well-aligned**: Current execution type matches content appropriately\n`; 545 | } 546 | 547 | if (analysis.suggestedGates.length > 0) { 548 | recommendation += `\n🔒 **Suggested Quality Gates**: ${analysis.suggestedGates.join(', ')}\n`; 549 | } 550 | 551 | return createPromptResponse(recommendation, "analyze_type", { 552 | promptId: args.id, 553 | analysisResult: { classification: analysis, feedback: '', suggestions: [] } 554 | }); 555 | } 556 | 557 | // Additional helper methods (maintaining original API) 558 | private async createBasicPrompt(args: any): Promise<ToolResponse> { 559 | // Implementation delegated to createPrompt with specific mode 560 | return this.createPrompt({ 561 | ...args, 562 | executionMode: 'prompt' 563 | }); 564 | } 565 | 566 | private async createFrameworkTemplate(args: any): Promise<ToolResponse> { 567 | // Implementation delegated to createPrompt with framework context 568 | return this.createPrompt({ 569 | ...args, 570 | executionMode: 'template' 571 | }); 572 | } 573 | 574 | private async migratePromptType(args: any): Promise<ToolResponse> { 575 | // Simplified implementation - could be expanded with migration module 576 | validateRequiredFields(args, ['id', 'target_type']); 577 | 578 | const prompt = this.convertedPrompts.find(p => p.id === args.id); 579 | if (!prompt) { 580 | return createErrorResponse(`Prompt not found: ${args.id}`, { 581 | tool: "prompt_manager", 582 | operation: "migrate_type", 583 | errorType: "validation", 584 | severity: "medium" 585 | }); 586 | } 587 | 588 | return createPromptResponse( 589 | `🔄 Migration from ${prompt.id} to ${args.target_type} would be implemented here`, 590 | "migrate_type", 591 | { promptId: args.id } 592 | ); 593 | } 594 | 595 | private async modifyPrompt(args: any): Promise<ToolResponse> { 596 | // Simplified implementation - full modify logic could be in operations module 597 | validateRequiredFields(args, ['id', 'section_name', 'new_content']); 598 | 599 | return createPromptResponse( 600 | `✏️ **Section Modified**: ${args.section_name} in ${args.id}`, 601 | "modify", 602 | { promptId: args.id } 603 | ); 604 | } 605 | 606 | private async reloadPrompts(args: any): Promise<ToolResponse> { 607 | const reason = args.reason || "Manual reload requested"; 608 | 609 | let response = `🔄 **Reloading Prompts System**\n\n`; 610 | response += `**Reason**: ${reason}\n`; 611 | response += `**Mode**: ${args.full_restart ? 'Full Server Restart' : 'Hot Reload'}\n\n`; 612 | 613 | if (args.full_restart) { 614 | setTimeout(() => this.onRestart(reason), 1000); 615 | response += `⚡ **Server restart initiated**... Please wait for reconnection.\n`; 616 | } else { 617 | await this.onRefresh(); 618 | response += `✅ **Hot reload completed** - All prompts refreshed from disk.\n`; 619 | } 620 | 621 | return createPromptResponse(response, "reload", { 622 | promptId: "system", 623 | affectedFiles: args.full_restart ? ["server"] : ["prompts"] 624 | }); 625 | } 626 | 627 | // Helper methods 628 | private findPromptDependencies(promptId: string): ConvertedPrompt[] { 629 | return this.convertedPrompts.filter(prompt => { 630 | if (!prompt.chainSteps || prompt.chainSteps.length === 0) return false; 631 | return prompt.chainSteps.some((step: any) => step.promptId === promptId); 632 | }); 633 | } 634 | 635 | private getExecutionTypeIcon(executionType: string): string { 636 | switch (executionType) { 637 | case 'prompt': return '⚡'; 638 | case 'template': return '🧠'; 639 | case 'chain': return '🔗'; 640 | default: return '❓'; 641 | } 642 | } 643 | 644 | private async handleSystemRefresh(fullRestart: boolean = false, reason: string): Promise<void> { 645 | if (fullRestart) { 646 | setTimeout(() => this.onRestart(reason), 1000); 647 | } else { 648 | await this.onRefresh(); 649 | } 650 | } 651 | 652 | /** 653 | * Analyze prompt gates and provide recommendations 654 | */ 655 | private async analyzePromptGates(args: any): Promise<ToolResponse> { 656 | validateRequiredFields(args, ['id']); 657 | 658 | const prompt = this.convertedPrompts.find(p => p.id === args.id); 659 | if (!prompt) { 660 | return createErrorResponse(`Prompt not found: ${args.id}`, { 661 | tool: "prompt_manager", 662 | operation: "analyze_gates", 663 | errorType: "validation", 664 | severity: "medium" 665 | }); 666 | } 667 | 668 | const analysis = await this.gateAnalyzer.analyzePromptForGates(prompt); 669 | 670 | let response = `🔒 **Gate Analysis**: ${prompt.name}\n\n`; 671 | response += `📊 **Analysis Summary**:\n`; 672 | response += `- **Confidence**: ${Math.round(analysis.confidence * 100)}%\n`; 673 | response += `- **Recommended Gates**: ${analysis.recommendedGates.length}\n`; 674 | response += `- **Suggested Temporary Gates**: ${analysis.suggestedTemporaryGates.length}\n\n`; 675 | 676 | if (analysis.recommendedGates.length > 0) { 677 | response += `🎯 **Recommended Persistent Gates**:\n`; 678 | analysis.recommendedGates.forEach(gate => { 679 | response += `- ${gate}\n`; 680 | }); 681 | response += `\n`; 682 | } 683 | 684 | if (analysis.suggestedTemporaryGates.length > 0) { 685 | response += `⚡ **Suggested Temporary Gates**:\n`; 686 | analysis.suggestedTemporaryGates.forEach(gate => { 687 | response += `- **${gate.name}** (${gate.type}, ${gate.scope})\n`; 688 | response += ` ${gate.description}\n`; 689 | }); 690 | response += `\n`; 691 | } 692 | 693 | if (analysis.reasoning.length > 0) { 694 | response += `🧠 **Analysis Reasoning**:\n`; 695 | analysis.reasoning.forEach((reason, i) => { 696 | response += `${i + 1}. ${reason}\n`; 697 | }); 698 | response += `\n`; 699 | } 700 | 701 | response += `📋 **Suggested Gate Configuration**:\n`; 702 | response += `\`\`\`json\n${JSON.stringify(analysis.gateConfigurationPreview, null, 2)}\n\`\`\`\n`; 703 | 704 | return createPromptResponse(response, "analyze_gates", { 705 | promptId: args.id, 706 | category: prompt.category, 707 | analysisResult: analysis 708 | }); 709 | } 710 | 711 | /** 712 | * Suggest temporary gates for execution context 713 | */ 714 | private async suggestTemporaryGates(args: any): Promise<ToolResponse> { 715 | validateRequiredFields(args, ['execution_context']); 716 | 717 | const context = args.execution_context; 718 | const suggestedGates = await this.gateAnalyzer.suggestGatesForContext(context); 719 | 720 | let response = `⚡ **Temporary Gate Suggestions**\n\n`; 721 | response += `📋 **Context**: ${context.executionType} execution in ${context.category} category\n`; 722 | response += `🎚️ **Complexity**: ${context.complexity}\n\n`; 723 | 724 | if (suggestedGates.length > 0) { 725 | response += `🔒 **Suggested Gates**:\n`; 726 | suggestedGates.forEach((gate, i) => { 727 | response += `${i + 1}. ${gate}\n`; 728 | }); 729 | } else { 730 | response += `ℹ️ No specific gate suggestions for this context - default gates will apply.\n`; 731 | } 732 | 733 | response += `\n💡 **Usage**: Use these suggestions when creating or updating prompts to ensure appropriate quality gates are applied.\n`; 734 | 735 | return createPromptResponse(response, "suggest_temporary_gates", { 736 | promptId: "context-based", 737 | category: context.category || "general", 738 | analysisResult: { suggestions: suggestedGates } 739 | }); 740 | } 741 | 742 | /** 743 | * Create prompt with enhanced gate configuration 744 | */ 745 | private async createPromptWithGates(args: any): Promise<ToolResponse> { 746 | // USING ERROR LEVEL FOR GUARANTEED VISIBILITY 747 | this.logger.error(`[GATE-TRACE] 🎯 createPromptWithGates called for prompt: ${args.id}`); 748 | this.logger.error(`[GATE-TRACE] Gate config raw data:`, { 749 | hasGateConfig: !!args.gate_configuration, 750 | gateConfigType: typeof args.gate_configuration, 751 | gateConfigRaw: args.gate_configuration, 752 | hasSuggestedGates: !!args.suggested_gates 753 | }); 754 | 755 | validateRequiredFields(args, ['id', 'name', 'description', 'user_message_template']); 756 | 757 | // Validate and parse gate configuration 758 | let gateConfiguration: any = null; 759 | if (args.gate_configuration) { 760 | this.logger.info(`[GATE-DEBUG] Processing gate_configuration for ${args.id}`); 761 | try { 762 | gateConfiguration = typeof args.gate_configuration === 'string' 763 | ? JSON.parse(args.gate_configuration) 764 | : args.gate_configuration; 765 | this.logger.debug(`[GATE-DEBUG] Parsed gate configuration:`, gateConfiguration); 766 | } catch (error) { 767 | this.logger.error(`[GATE-DEBUG] Failed to parse gate configuration:`, error); 768 | throw new ValidationError(`Invalid gate configuration JSON: ${error instanceof Error ? error.message : String(error)}`); 769 | } 770 | } else if (args.suggested_gates) { 771 | this.logger.info(`[GATE-DEBUG] Auto-generating from suggested_gates for ${args.id}`); 772 | // Auto-generate basic gate configuration from suggested gates 773 | // Extract gate names from gate objects 774 | const gateNames = Array.isArray(args.suggested_gates) 775 | ? args.suggested_gates.map((gate: any) => gate.name) 776 | : [args.suggested_gates.name]; 777 | 778 | gateConfiguration = { 779 | include: gateNames, 780 | framework_gates: true 781 | }; 782 | this.logger.debug(`[GATE-DEBUG] Auto-generated gate configuration with extracted names:`, gateConfiguration); 783 | } else { 784 | this.logger.warn(`[GATE-DEBUG] No gate configuration or suggested gates found for ${args.id}`); 785 | } 786 | 787 | // Create prompt with gates 788 | const enhancedArgs = { 789 | ...args, 790 | gate_configuration: gateConfiguration 791 | }; 792 | 793 | this.logger.debug(`[GATE-DEBUG] Enhanced args being passed to createPrompt:`, { 794 | id: enhancedArgs.id, 795 | hasGateConfig: !!enhancedArgs.gate_configuration, 796 | gateConfigContent: enhancedArgs.gate_configuration 797 | }); 798 | 799 | return await this.createPrompt(enhancedArgs); 800 | } 801 | 802 | /** 803 | * Update gate configuration for existing prompt 804 | */ 805 | private async updatePromptGates(args: any): Promise<ToolResponse> { 806 | validateRequiredFields(args, ['id']); 807 | 808 | const currentPrompt = this.convertedPrompts.find(p => p.id === args.id); 809 | if (!currentPrompt) { 810 | throw new PromptError(`Prompt not found: ${args.id}`); 811 | } 812 | 813 | // Parse new gate configuration 814 | let gateConfiguration: any = null; 815 | if (args.gate_configuration) { 816 | try { 817 | gateConfiguration = typeof args.gate_configuration === 'string' 818 | ? JSON.parse(args.gate_configuration) 819 | : args.gate_configuration; 820 | } catch (error) { 821 | throw new ValidationError(`Invalid gate configuration JSON: ${error instanceof Error ? error.message : String(error)}`); 822 | } 823 | } 824 | 825 | // Update only the gate configuration 826 | const updateArgs = { 827 | id: args.id, 828 | gate_configuration: gateConfiguration 829 | }; 830 | 831 | const result = await this.updatePrompt(updateArgs); 832 | 833 | let response = `🔧 **Gate Configuration Updated**: ${currentPrompt.name} (${args.id})\n\n`; 834 | response += `✅ Gate configuration has been updated successfully.\n`; 835 | 836 | if (gateConfiguration) { 837 | response += `📋 **Applied Configuration**:\n`; 838 | if (gateConfiguration.include) { 839 | response += `- Include Gates: ${gateConfiguration.include.join(', ')}\n`; 840 | } 841 | if (gateConfiguration.exclude) { 842 | response += `- Exclude Gates: ${gateConfiguration.exclude.join(', ')}\n`; 843 | } 844 | if (gateConfiguration.temporary_gates) { 845 | response += `- Temporary Gates: ${gateConfiguration.temporary_gates.length} gates defined\n`; 846 | } 847 | response += `- Framework Gates: ${gateConfiguration.framework_gates !== false ? 'Enabled' : 'Disabled'}\n`; 848 | } 849 | 850 | return createPromptResponse(response, "update_gates", { 851 | promptId: args.id, 852 | category: currentPrompt.category, 853 | analysisResult: { gateConfiguration } 854 | }); 855 | } 856 | 857 | /** 858 | * Add temporary gates to existing prompt configuration 859 | * Phase 3 Fix: This now adds gates to in-memory configuration only (no file writes) 860 | * Gates are truly temporary and will be activated during prompt execution 861 | */ 862 | private async addTemporaryGates(args: any): Promise<ToolResponse> { 863 | validateRequiredFields(args, ['id', 'temporary_gates']); 864 | 865 | const currentPrompt = this.convertedPrompts.find(p => p.id === args.id); 866 | if (!currentPrompt) { 867 | throw new PromptError(`Prompt not found: ${args.id}`); 868 | } 869 | 870 | // Parse temporary gates 871 | let temporaryGates: any[]; 872 | try { 873 | temporaryGates = typeof args.temporary_gates === 'string' 874 | ? JSON.parse(args.temporary_gates) 875 | : args.temporary_gates; 876 | 877 | if (!Array.isArray(temporaryGates)) { 878 | throw new Error("temporary_gates must be an array"); 879 | } 880 | } catch (error) { 881 | throw new ValidationError(`Invalid temporary gates configuration: ${error instanceof Error ? error.message : String(error)}`); 882 | } 883 | 884 | // Phase 3 Fix: Update in-memory configuration only - NO FILE WRITES 885 | // This makes gates truly temporary - they exist only in memory and expire/cleanup automatically 886 | // Use enhancedGateConfiguration which supports temporary_gates 887 | const existingGateConfig = currentPrompt.enhancedGateConfiguration || currentPrompt.gateConfiguration || {}; 888 | currentPrompt.enhancedGateConfiguration = { 889 | ...existingGateConfig, 890 | temporary_gates: temporaryGates, 891 | gate_scope: args.gate_scope || 'execution', 892 | inherit_chain_gates: args.inherit_chain_gates !== false 893 | }; 894 | 895 | this.logger.info(`[TEMP GATES] Added ${temporaryGates.length} temporary gates to ${args.id} (in-memory only, no file write)`, { 896 | promptId: args.id, 897 | gateCount: temporaryGates.length, 898 | scope: args.gate_scope || 'execution' 899 | }); 900 | 901 | let response = `⚡ **Temporary Gates Added (In-Memory)**: ${currentPrompt.name} (${args.id})\n\n`; 902 | response += `✅ ${temporaryGates.length} temporary gates added to in-memory configuration.\n`; 903 | response += `⚠️ **Note**: Gates are temporary and will NOT be written to disk. They expire after use.\n\n`; 904 | 905 | response += `🔒 **Added Temporary Gates**:\n`; 906 | temporaryGates.forEach((gate, i) => { 907 | response += `${i + 1}. **${gate.name}** (${gate.type}, ${gate.scope})\n`; 908 | response += ` - ${gate.description}\n`; 909 | }); 910 | 911 | response += `\n📋 **Configuration**:\n`; 912 | response += `- Gate Scope: ${args.gate_scope || 'execution'}\n`; 913 | response += `- Inherit Chain Gates: ${args.inherit_chain_gates !== false ? 'Yes' : 'No'}\n`; 914 | response += `- Persistence: In-memory only (no file writes)\n`; 915 | response += `- Lifecycle: Will be auto-activated on next prompt execution\n`; 916 | 917 | return createPromptResponse(response, "add_temporary_gates", { 918 | promptId: args.id, 919 | category: currentPrompt.category, 920 | analysisResult: { 921 | temporaryGatesAdded: temporaryGates.length, 922 | inMemoryOnly: true, 923 | gateConfiguration: currentPrompt.enhancedGateConfiguration 924 | } 925 | }); 926 | } 927 | 928 | private handleError(error: unknown, context: string): ToolResponse { 929 | const { message, isError } = utilsHandleError(error, context, this.logger); 930 | return createErrorResponse(message, { 931 | tool: "prompt_manager", 932 | operation: context, 933 | errorType: "system", 934 | severity: "medium" 935 | }); 936 | } 937 | } 938 | 939 | /** 940 | * Create consolidated prompt manager - maintains original factory function API 941 | */ 942 | export function createConsolidatedPromptManager( 943 | logger: Logger, 944 | mcpServer: any, 945 | configManager: ConfigManager, 946 | semanticAnalyzer: ContentAnalyzer, 947 | frameworkStateManager: FrameworkStateManager | undefined, 948 | frameworkManager: FrameworkManager | undefined, 949 | onRefresh: () => Promise<void>, 950 | onRestart: (reason: string) => Promise<void> 951 | ): ConsolidatedPromptManager { 952 | return new ConsolidatedPromptManager( 953 | logger, 954 | mcpServer, 955 | configManager, 956 | semanticAnalyzer, 957 | frameworkStateManager, 958 | frameworkManager, 959 | onRefresh, 960 | onRestart 961 | ); 962 | } ``` -------------------------------------------------------------------------------- /plans/nunjucks-dynamic-chain-orchestration.md: -------------------------------------------------------------------------------- ```markdown 1 | # Nunjucks Dynamic Chain Orchestration - Comprehensive Implementation Plan 2 | 3 | **Created**: 2025-10-05 4 | **Status**: Planning 5 | **Priority**: High - Strategic Architecture Enhancement 6 | **Impact**: Enables result-based adaptive prompts, quality-driven chains, dynamic execution flows 7 | 8 | ## Executive Summary 9 | 10 | **Critical Discovery**: Nunjucks templates render on EACH chain step with access to previous step results. This enables powerful result-based conditional logic and adaptive prompt instructions that we're currently not leveraging. 11 | 12 | **Core Opportunity**: Transform static chain steps into intelligent, adaptive prompts that modify their behavior based on: 13 | - Previous step quality scores 14 | - Validation results from earlier steps 15 | - Accumulated complexity metrics 16 | - Error conditions and recovery needs 17 | - Content characteristics discovered during execution 18 | 19 | **Strategic Goal**: Build a sophisticated chain orchestration system where prompts intelligently adapt their instructions, depth, and approach based on runtime results. 20 | 21 | --- 22 | 23 | ## Table of Contents 24 | 25 | 1. [Current State Analysis](#current-state-analysis) 26 | 2. [Nunjucks Capabilities in Chains](#nunjucks-capabilities-in-chains) 27 | 3. [Result-Based Conditional Patterns](#result-based-conditional-patterns) 28 | 4. [Quality-Driven Adaptive Prompts](#quality-driven-adaptive-prompts) 29 | 5. [Implementation Strategy](#implementation-strategy) 30 | 6. [Example Transformations](#example-transformations) 31 | 7. [Best Practices & Patterns](#best-practices--patterns) 32 | 8. [Performance Considerations](#performance-considerations) 33 | 9. [Future Enhancements](#future-enhancements) 34 | 35 | --- 36 | 37 | ## Current State Analysis 38 | 39 | ### What We Have Now 40 | 41 | **Chain Execution Flow (Actual)**: 42 | ``` 43 | Step 1: analysis_step 44 | → Load template "analysis_step.md" 45 | → Render with Nunjucks (variables: {input: "user data"}) 46 | → Execute with LLM 47 | → Output: {analysis: "detailed analysis", confidence: 0.85} 48 | 49 | Step 2: validation_step 50 | → Load template "validation_step.md" 51 | → Render with Nunjucks (variables: { 52 | analysis: "detailed analysis", 53 | confidence: 0.85, 54 | quality_threshold: 0.8 55 | }) 56 | → Execute with LLM 57 | → Output: {validation_score: 0.6, issues: ["accuracy", "citations"]} 58 | 59 | Step 3: refinement_step 60 | → Load template "refinement_step.md" 61 | → Render with Nunjucks (variables: { 62 | analysis: "detailed analysis", 63 | validation_score: 0.6, 64 | issues: ["accuracy", "citations"] 65 | }) 66 | → Execute with LLM 67 | → Output: {refined_analysis: "improved analysis"} 68 | ``` 69 | 70 | **Key Insight**: Each step receives ALL previous step outputs as variables! 71 | 72 | ### What We're NOT Using 73 | 74 | **Current Prompt Pattern** (Passive): 75 | ```markdown 76 | # Refinement Step 77 | 78 | Refine this analysis: {{analysis}} 79 | 80 | Previous validation score: {{validation_score}} 81 | Issues identified: {{issues}} 82 | 83 | Please improve the analysis addressing the identified issues. 84 | ``` 85 | 86 | **What Nunjucks Enables** (Active): 87 | ```markdown 88 | # Refinement Step 89 | 90 | Refine this analysis: {{analysis}} 91 | 92 | {% if validation_score < 0.7 %} 93 | ## ⚠️ CRITICAL QUALITY ISSUES DETECTED 94 | 95 | Validation Score: {{validation_score}} (Target: ≥0.80) 96 | 97 | ### Priority Issues Requiring Immediate Attention: 98 | {% for issue in issues %} 99 | - **{{issue}}**: Apply comprehensive remediation 100 | {% endfor %} 101 | 102 | ### Enhanced Refinement Protocol: 103 | 1. **Evidence Strengthening**: Add authoritative citations for all claims 104 | 2. **Accuracy Verification**: Cross-reference facts against reliable sources 105 | 3. **Clarity Enhancement**: Restructure unclear sections with examples 106 | 4. **Completeness Check**: Address all gaps identified in validation 107 | 5. **Quality Validation**: Self-assess against original standards 108 | 109 | **Target Outcome**: Achieve validation score ≥0.80 with zero critical issues. 110 | 111 | {% elif validation_score < 0.9 %} 112 | ## Moderate Improvement Required 113 | 114 | Validation Score: {{validation_score}} (Good, targeting excellence) 115 | 116 | ### Issues to Address: 117 | {% for issue in issues %} 118 | - {{issue}} 119 | {% endfor %} 120 | 121 | Apply targeted refinements: 122 | - Enhance clarity where needed 123 | - Add supporting examples for complex concepts 124 | - Strengthen key arguments with additional evidence 125 | 126 | {% else %} 127 | ## Excellent Quality - Final Polish 128 | 129 | Validation Score: {{validation_score}} (Excellent!) 130 | 131 | Apply publication-ready polish: 132 | - Fine-tune language for professional tone 133 | - Ensure consistent terminology 134 | - Add visual formatting enhancements 135 | - Optimize for reader comprehension 136 | 137 | {% endif %} 138 | 139 | --- 140 | 141 | **Original Analysis:** 142 | {{analysis}} 143 | 144 | **Refinement Instructions**: Focus your improvements based on the quality level indicated above. 145 | ``` 146 | 147 | **The Difference**: 148 | - **Passive**: LLM sees data, decides what to do 149 | - **Active**: Template provides specific, quality-appropriate instructions 150 | 151 | --- 152 | 153 | ## Nunjucks Capabilities in Chains 154 | 155 | ### 1. Result-Based Conditionals 156 | 157 | **Access Previous Step Outputs**: 158 | ```nunjucks 159 | {% if previous_step_output.contains("error") %} 160 | {# Error handling instructions #} 161 | {% elif previous_step_output.quality_score < threshold %} 162 | {# Quality improvement instructions #} 163 | {% else %} 164 | {# Standard processing instructions #} 165 | {% endif %} 166 | ``` 167 | 168 | **Available in Step Context**: 169 | - All outputs from previous steps (mapped by outputMapping) 170 | - Original input variables 171 | - Chain configuration parameters 172 | - Step execution metadata 173 | 174 | ### 2. Complexity-Driven Adaptation 175 | 176 | **Calculate from Accumulated State**: 177 | ```nunjucks 178 | {% set total_items = sources|length + topics|length + constraints|length %} 179 | {% set complexity_level = "low" %} 180 | {% if total_items > 20 %} 181 | {% set complexity_level = "maximum" %} 182 | {% elif total_items > 10 %} 183 | {% set complexity_level = "high" %} 184 | {% elif total_items > 5 %} 185 | {% set complexity_level = "standard" %} 186 | {% endif %} 187 | 188 | {% if complexity_level == "maximum" %} 189 | ## 🔥 MAXIMUM COMPLEXITY ANALYSIS REQUIRED 190 | 191 | With {{total_items}} factors to consider, apply systematic framework: 192 | 193 | ### Phase 1: Categorization 194 | - Group sources by type and relevance 195 | - Map topic relationships and dependencies 196 | - Prioritize constraints by impact 197 | 198 | ### Phase 2: Deep Analysis 199 | [Detailed complex analysis instructions...] 200 | 201 | ### Phase 3: Synthesis 202 | [Complex synthesis instructions...] 203 | 204 | {% elif complexity_level == "high" %} 205 | ## ⚡ HIGH COMPLEXITY ANALYSIS 206 | 207 | {{total_items}} factors identified. Apply structured analysis: 208 | [Moderate complexity instructions...] 209 | 210 | {% else %} 211 | ## 📊 STANDARD ANALYSIS 212 | 213 | Focus on core insights from {{total_items}} key factors: 214 | [Simple analysis instructions...] 215 | 216 | {% endif %} 217 | ``` 218 | 219 | ### 3. Quality-Based Instruction Customization 220 | 221 | **Adapt Depth Based on Previous Quality**: 222 | ```nunjucks 223 | {% if step2_quality_score > 0.9 %} 224 | {# High quality - proceed with advanced analysis #} 225 | Apply sophisticated analytical frameworks and advanced methodologies... 226 | 227 | {% elif step2_quality_score > 0.7 %} 228 | {# Moderate quality - provide structured guidance #} 229 | Follow this systematic approach to build upon the foundation... 230 | 231 | {% else %} 232 | {# Low quality - provide detailed step-by-step instructions #} 233 | Use this detailed framework with explicit examples at each step... 234 | 235 | {% endif %} 236 | ``` 237 | 238 | ### 4. Error Recovery and Adaptive Routing 239 | 240 | **Handle Validation Failures**: 241 | ```nunjucks 242 | {% if validation_result.passed == false %} 243 | 244 | ## 🚨 VALIDATION FAILURE - RECOVERY MODE ACTIVATED 245 | 246 | **Failed Checks**: 247 | {% for check in validation_result.failed_checks %} 248 | - {{check.name}}: {{check.reason}} 249 | {% endfor %} 250 | 251 | ### Recovery Protocol: 252 | 253 | {% if "accuracy" in validation_result.failed_checks|map(attribute='name') %} 254 | **Accuracy Issues Detected** 255 | 1. Verify all factual claims against authoritative sources 256 | 2. Remove or qualify uncertain statements 257 | 3. Add citations for key claims 258 | {% endif %} 259 | 260 | {% if "completeness" in validation_result.failed_checks|map(attribute='name') %} 261 | **Completeness Issues Detected** 262 | 1. Review requirements checklist: {{validation_result.requirements}} 263 | 2. Identify and address gaps 264 | 3. Ensure comprehensive coverage 265 | {% endif %} 266 | 267 | [Additional recovery instructions based on specific failures...] 268 | 269 | {% else %} 270 | {# Validation passed - proceed normally #} 271 | {% endif %} 272 | ``` 273 | 274 | ### 5. Accumulated State Tracking 275 | 276 | **Use History from Multiple Steps**: 277 | ```nunjucks 278 | {# Step 5 has access to outputs from Steps 1-4 #} 279 | 280 | {% if step1_analysis.insights|length > 10 and step3_validation.score > 0.8 %} 281 | {# High quality, rich content - apply advanced synthesis #} 282 | {% elif step2_research.sources|length < 3 %} 283 | {# Limited sources - acknowledge and adapt #} 284 | Note: Analysis based on {{step2_research.sources|length}} sources. 285 | Apply appropriate confidence qualifiers... 286 | {% endif %} 287 | ``` 288 | 289 | --- 290 | 291 | ## Result-Based Conditional Patterns 292 | 293 | ### Pattern 1: Quality Score Adaptation 294 | 295 | **Use Case**: Adjust refinement depth based on validation results 296 | 297 | **Chain Definition**: 298 | ```json 299 | { 300 | "steps": [ 301 | { 302 | "promptId": "initial_analysis", 303 | "outputMapping": {"analysis": "initial_output"} 304 | }, 305 | { 306 | "promptId": "quality_validation", 307 | "inputMapping": {"content": "initial_output"}, 308 | "outputMapping": {"score": "quality_score", "issues": "quality_issues"} 309 | }, 310 | { 311 | "promptId": "adaptive_refinement", 312 | "inputMapping": { 313 | "original": "initial_output", 314 | "score": "quality_score", 315 | "issues": "quality_issues" 316 | } 317 | } 318 | ] 319 | } 320 | ``` 321 | 322 | **Prompt Template** (`adaptive_refinement.md`): 323 | ```nunjucks 324 | # Adaptive Refinement 325 | 326 | Original Content: {{original}} 327 | Quality Score: {{score}} 328 | 329 | {% if score < 0.6 %} 330 | ## 🔴 COMPREHENSIVE REBUILD REQUIRED 331 | 332 | Score: {{score}}/1.0 - Below acceptable threshold 333 | 334 | ### Critical Issues: 335 | {% for issue in issues %} 336 | - {{issue.category}}: {{issue.description}} 337 | **Action Required**: {{issue.remedy}} 338 | {% endfor %} 339 | 340 | ### Rebuild Protocol: 341 | 1. Restart analysis from first principles 342 | 2. Apply rigorous methodology for each issue category 343 | 3. Implement all recommended remedies 344 | 4. Self-validate before submission 345 | 346 | Expected Outcome: Achieve minimum score of 0.75 347 | 348 | {% elif score < 0.8 %} 349 | ## 🟡 TARGETED IMPROVEMENTS NEEDED 350 | 351 | Score: {{score}}/1.0 - Good foundation, needs enhancement 352 | 353 | ### Focus Areas: 354 | {% for issue in issues %} 355 | - {{issue.category}}: {{issue.description}} 356 | {% endfor %} 357 | 358 | ### Improvement Strategy: 359 | 1. Address each issue systematically 360 | 2. Enhance clarity and supporting evidence 361 | 3. Strengthen weak areas identified above 362 | 363 | Target Score: ≥0.85 364 | 365 | {% else %} 366 | ## 🟢 MINOR REFINEMENTS 367 | 368 | Score: {{score}}/1.0 - Excellent quality 369 | 370 | Polish for publication: 371 | - Fine-tune language precision 372 | - Enhance readability and flow 373 | - Add final professional touches 374 | 375 | {% endif %} 376 | ``` 377 | 378 | ### Pattern 2: Error-Driven Recovery 379 | 380 | **Use Case**: Adapt to errors in previous steps 381 | 382 | **Template Pattern**: 383 | ```nunjucks 384 | {% if previous_error %} 385 | 386 | ## Error Recovery Mode 387 | 388 | Error Type: {{previous_error.type}} 389 | Error Message: {{previous_error.message}} 390 | 391 | {% if previous_error.type == "missing_data" %} 392 | ### Data Recovery Strategy: 393 | 1. Identify alternative data sources 394 | 2. Proceed with available information 395 | 3. Clearly document limitations 396 | 4. Provide qualified conclusions 397 | 398 | {% elif previous_error.type == "validation_failure" %} 399 | ### Validation Recovery: 400 | 1. Review failed validation criteria: {{previous_error.failed_criteria}} 401 | 2. Address each criterion systematically 402 | 3. Re-validate after corrections 403 | 404 | {% elif previous_error.type == "timeout" %} 405 | ### Timeout Recovery: 406 | Previous step timed out. Simplify approach: 407 | 1. Reduce scope to essential elements 408 | 2. Apply streamlined methodology 409 | 3. Focus on high-priority outputs 410 | 411 | {% endif %} 412 | 413 | {% else %} 414 | {# No error - proceed normally #} 415 | [Standard instructions] 416 | {% endif %} 417 | ``` 418 | 419 | ### Pattern 3: Complexity Escalation 420 | 421 | **Use Case**: Increase analysis depth if initial attempt is insufficient 422 | 423 | **Multi-Step Chain**: 424 | ```json 425 | { 426 | "steps": [ 427 | {"promptId": "quick_analysis", "outputMapping": {"result": "quick_result", "complexity": "detected_complexity"}}, 428 | {"promptId": "assessment", "outputMapping": {"adequate": "is_sufficient"}}, 429 | {"promptId": "deep_analysis_conditional", "inputMapping": { 430 | "quick_result": "quick_result", 431 | "adequate": "is_sufficient", 432 | "complexity": "detected_complexity" 433 | }} 434 | ] 435 | } 436 | ``` 437 | 438 | **Template** (`deep_analysis_conditional.md`): 439 | ```nunjucks 440 | {% if adequate == false or detected_complexity > 7 %} 441 | 442 | ## Deep Analysis Required 443 | 444 | Initial analysis: {{quick_result}} 445 | Complexity Level: {{detected_complexity}}/10 446 | Assessment: Insufficient depth 447 | 448 | ### Enhanced Analysis Framework: 449 | 450 | {% if detected_complexity > 8 %} 451 | **MAXIMUM DEPTH ANALYSIS** 452 | 1. Multi-dimensional examination 453 | 2. Cross-referencing from multiple perspectives 454 | 3. Advanced pattern recognition 455 | 4. Predictive implications analysis 456 | 457 | {% else %} 458 | **STANDARD DEEP ANALYSIS** 459 | 1. Comprehensive examination 460 | 2. Relationship mapping 461 | 3. Implication analysis 462 | 463 | {% endif %} 464 | 465 | {% else %} 466 | 467 | ## Quick Analysis Sufficient 468 | 469 | Initial result meets requirements: 470 | {{quick_result}} 471 | 472 | Apply minor enhancements only. 473 | 474 | {% endif %} 475 | ``` 476 | 477 | ### Pattern 4: Format Adaptation 478 | 479 | **Use Case**: Change output format based on content characteristics 480 | 481 | **Template**: 482 | ```nunjucks 483 | {% set content_type = "unknown" %} 484 | {% if "code" in step1_output or "function" in step1_output %} 485 | {% set content_type = "technical" %} 486 | {% elif "story" in step1_output or "narrative" in step1_output %} 487 | {% set content_type = "narrative" %} 488 | {% elif "data" in step1_output or "metric" in step1_output %} 489 | {% set content_type = "analytical" %} 490 | {% endif %} 491 | 492 | {% if content_type == "technical" %} 493 | ## Technical Documentation Format 494 | 495 | Content: {{step1_output}} 496 | 497 | Structure as: 498 | - Code examples with syntax highlighting 499 | - API reference format 500 | - Technical specifications table 501 | 502 | {% elif content_type == "narrative" %} 503 | ## Narrative Format 504 | 505 | Content: {{step1_output}} 506 | 507 | Structure as: 508 | - Story-driven presentation 509 | - Chronological flow 510 | - Engaging narrative elements 511 | 512 | {% elif content_type == "analytical" %} 513 | ## Analytical Report Format 514 | 515 | Content: {{step1_output}} 516 | 517 | Structure as: 518 | - Executive summary 519 | - Data visualizations 520 | - Statistical analysis 521 | - Recommendations 522 | 523 | {% endif %} 524 | ``` 525 | 526 | --- 527 | 528 | ## Quality-Driven Adaptive Prompts 529 | 530 | ### Architecture 531 | 532 | **Quality Assessment → Adaptive Instructions → Validated Output** 533 | 534 | ``` 535 | ┌─────────────────┐ 536 | │ Input Data │ 537 | └────────┬────────┘ 538 | ↓ 539 | ┌─────────────────┐ 540 | │ Step 1: │ 541 | │ Initial Work │ 542 | └────────┬────────┘ 543 | ↓ 544 | ┌─────────────────┐ 545 | │ Step 2: │ 546 | │ Quality Check │ 547 | │ (outputs score)│ 548 | └────────┬────────┘ 549 | ↓ 550 | ┌─────────────────┐ 551 | │ Step 3: │ 552 | │ Adaptive Work │ ← Nunjucks adapts based on score! 553 | │ {% if score %}│ 554 | └────────┬────────┘ 555 | ↓ 556 | ┌─────────────────┐ 557 | │ Final Output │ 558 | └─────────────────┘ 559 | ``` 560 | 561 | ### Quality Metrics to Leverage 562 | 563 | **Step Outputs Can Include**: 564 | ```json 565 | { 566 | "content": "...", 567 | "quality_metrics": { 568 | "accuracy_score": 0.85, 569 | "completeness_score": 0.90, 570 | "clarity_score": 0.75, 571 | "overall_score": 0.83 572 | }, 573 | "issues": [ 574 | {"category": "accuracy", "severity": "medium", "location": "paragraph 3"}, 575 | {"category": "clarity", "severity": "low", "location": "section 2"} 576 | ], 577 | "recommendations": ["add citations", "clarify terminology"] 578 | } 579 | ``` 580 | 581 | **Template Uses Metrics**: 582 | ```nunjucks 583 | {% if quality_metrics.accuracy_score < 0.8 %} 584 | Focus on accuracy: {{quality_metrics.accuracy_score}} below threshold 585 | Issues: {{issues|selectattr("category", "equalto", "accuracy")|list}} 586 | {% endif %} 587 | 588 | {% if quality_metrics.clarity_score < 0.8 %} 589 | Enhance clarity in: {{issues|selectattr("category", "equalto", "clarity")|map(attribute="location")|join(", ")}} 590 | {% endif %} 591 | ``` 592 | 593 | ### Adaptive Depth Control 594 | 595 | **Example: Research Depth Based on Initial Findings** 596 | 597 | ```nunjucks 598 | # Research Step 599 | 600 | {% set initial_source_count = step1_output.sources|length %} 601 | {% set initial_quality = step1_output.confidence %} 602 | 603 | {% if initial_source_count < 3 or initial_quality < 0.7 %} 604 | 605 | ## 🔍 EXPANDED RESEARCH REQUIRED 606 | 607 | Initial findings insufficient: 608 | - Sources: {{initial_source_count}} (target: ≥5) 609 | - Confidence: {{initial_quality}} (target: ≥0.80) 610 | 611 | ### Deep Research Protocol: 612 | 1. Expand source search to at least 5 authoritative references 613 | 2. Diversify source types (academic, industry, expert opinion) 614 | 3. Cross-validate findings across sources 615 | 4. Build comprehensive evidence base 616 | 617 | {% else %} 618 | 619 | ## ✓ Standard Research Process 620 | 621 | Initial findings provide solid foundation: 622 | - Sources: {{initial_source_count}} 623 | - Confidence: {{initial_quality}} 624 | 625 | ### Research Tasks: 626 | 1. Supplement existing findings 627 | 2. Fill identified gaps 628 | 3. Strengthen key conclusions 629 | 630 | {% endif %} 631 | 632 | Previous Findings: {{step1_output.summary}} 633 | 634 | [Continue with research based on depth level indicated above] 635 | ``` 636 | 637 | --- 638 | 639 | ## Implementation Strategy 640 | 641 | ### Phase 1: Identify High-Value Chains (Week 1) 642 | 643 | **Audit Current Chains**: 644 | 1. Review existing chain prompts 645 | 2. Identify steps that could benefit from adaptation 646 | 3. Map current variable passing patterns 647 | 4. Document quality metrics already available 648 | 649 | **Priority Candidates**: 650 | - `noteIntegration.md` - 7 steps, quality-sensitive 651 | - `create_docs_chain.md` - 5 steps, depth-variable 652 | - `video_notes_enhanced.md` - 6 steps, content-adaptive 653 | 654 | ### Phase 2: Design Adaptive Patterns (Week 1-2) 655 | 656 | **Create Pattern Library**: 657 | 1. **Quality-Based Adaptation** 658 | - Templates for score-driven instructions 659 | - Severity-based error handling 660 | - Validation-driven refinement 661 | 662 | 2. **Complexity-Based Adaptation** 663 | - Dynamic depth control 664 | - Resource allocation based on complexity 665 | - Methodology selection by difficulty 666 | 667 | 3. **Content-Based Adaptation** 668 | - Format selection based on content type 669 | - Structure adaptation to material 670 | - Example density based on technicality 671 | 672 | ### Phase 3: Implement Example Chains (Week 2-3) 673 | 674 | **Transform Existing Chains**: 675 | 676 | **Example 1: Note Integration Chain** 677 | 678 | Current `obsidian_metadata_optimizer.md`: 679 | ```nunjucks 680 | {{note_content}} 681 | {{vault_structure}} 682 | ``` 683 | 684 | Enhanced with quality adaptation: 685 | ```nunjucks 686 | {{note_content}} 687 | {{vault_structure}} 688 | 689 | {% if step3_refinement.quality_score %} 690 | Quality from previous step: {{step3_refinement.quality_score}} 691 | 692 | {% if step3_refinement.quality_score < 0.8 %} 693 | **Enhanced Metadata Required** 694 | Apply comprehensive metadata framework with: 695 | - Extended tag hierarchy (minimum 10 tags) 696 | - Full plugin integration metadata 697 | - Detailed connection network (≥5 related notes) 698 | - Advanced search keywords (≥15 terms) 699 | 700 | {% else %} 701 | **Standard Metadata** 702 | Apply professional metadata standards. 703 | {% endif %} 704 | 705 | {% endif %} 706 | ``` 707 | 708 | **Example 2: Documentation Chain** 709 | 710 | Transform `docs-review-refinement.md`: 711 | ```nunjucks 712 | {% if step3_content.technical_depth %} 713 | 714 | {% if step3_content.technical_depth == "advanced" and audience == "beginners" %} 715 | 716 | ## ⚠️ TECHNICAL DEPTH MISMATCH DETECTED 717 | 718 | Content Complexity: Advanced 719 | Target Audience: Beginners 720 | 721 | ### Adaptation Strategy: 722 | 1. Add explanatory sections for complex concepts 723 | 2. Include step-by-step walkthroughs 724 | 3. Provide glossary of technical terms 725 | 4. Add beginner-friendly examples 726 | 5. Create progressive disclosure sections (basic → advanced) 727 | 728 | {% elif step3_content.technical_depth == "basic" and audience == "experts" %} 729 | 730 | ## ⚡ DEPTH ENHANCEMENT REQUIRED 731 | 732 | Content Complexity: Basic 733 | Target Audience: Experts 734 | 735 | ### Enhancement Strategy: 736 | 1. Add advanced implementation details 737 | 2. Include edge case discussions 738 | 3. Provide performance optimization guidance 739 | 4. Add architectural considerations 740 | 5. Include expert-level best practices 741 | 742 | {% endif %} 743 | 744 | {% endif %} 745 | ``` 746 | 747 | ### Phase 4: Add Quality Metrics to Steps (Week 3-4) 748 | 749 | **Enhance Validation Steps**: 750 | 751 | Currently, validation steps might output: 752 | ```json 753 | {"validated": true, "content": "..."} 754 | ``` 755 | 756 | Enhance to output: 757 | ```json 758 | { 759 | "validated": true, 760 | "content": "...", 761 | "quality_score": 0.87, 762 | "accuracy_score": 0.90, 763 | "completeness_score": 0.85, 764 | "clarity_score": 0.85, 765 | "issues": [ 766 | {"type": "clarity", "severity": "low", "description": "Section 3 could be clearer"} 767 | ], 768 | "recommendations": ["add example in section 3"], 769 | "metadata": { 770 | "word_count": 1500, 771 | "complexity_level": 7, 772 | "technical_terms": 45 773 | } 774 | } 775 | ``` 776 | 777 | **Update Validation Prompts**: 778 | Add structured output requirements to validation steps: 779 | ```markdown 780 | Provide validation results in this structure: 781 | - quality_score: Overall score 0-1 782 | - accuracy_score: Factual accuracy 0-1 783 | - completeness_score: Coverage completeness 0-1 784 | - clarity_score: Clarity and readability 0-1 785 | - issues: Array of specific issues with severity 786 | - recommendations: Array of improvement suggestions 787 | ``` 788 | 789 | ### Phase 5: Create Template Helpers (Week 4) 790 | 791 | **Nunjucks Custom Filters**: 792 | 793 | Add custom filters to `jsonUtils.ts` nunjucksEnv: 794 | ```typescript 795 | nunjucksEnv.addFilter('quality_level', (score: number) => { 796 | if (score >= 0.9) return 'excellent'; 797 | if (score >= 0.8) return 'good'; 798 | if (score >= 0.7) return 'acceptable'; 799 | return 'needs_improvement'; 800 | }); 801 | 802 | nunjucksEnv.addFilter('severity_icon', (severity: string) => { 803 | const icons = { 804 | 'critical': '🔴', 805 | 'high': '🟠', 806 | 'medium': '🟡', 807 | 'low': '🟢' 808 | }; 809 | return icons[severity] || '⚪'; 810 | }); 811 | 812 | nunjucksEnv.addFilter('complexity_emoji', (level: number) => { 813 | if (level > 8) return '🔥'; 814 | if (level > 5) return '⚡'; 815 | return '📊'; 816 | }); 817 | ``` 818 | 819 | **Usage in Templates**: 820 | ```nunjucks 821 | Quality: {{quality_score|quality_level}} 822 | Severity: {{issue.severity|severity_icon}} {{issue.description}} 823 | Complexity: {{complexity_level|complexity_emoji}} Level {{complexity_level}} 824 | ``` 825 | 826 | ### Phase 6: Testing & Refinement (Week 4-5) 827 | 828 | **Test Matrix**: 829 | ``` 830 | Chain: noteIntegration 831 | Scenario 1: High quality input (score > 0.9) 832 | Expected: Standard processing 833 | Actual: [test result] 834 | 835 | Scenario 2: Medium quality (score 0.7-0.9) 836 | Expected: Targeted improvements 837 | Actual: [test result] 838 | 839 | Scenario 3: Low quality (score < 0.7) 840 | Expected: Comprehensive rebuild 841 | Actual: [test result] 842 | ``` 843 | 844 | **Validation**: 845 | - Execute chains with varying quality inputs 846 | - Verify conditional branches trigger correctly 847 | - Ensure template variables accessible 848 | - Confirm output meets quality targets 849 | 850 | --- 851 | 852 | ## Example Transformations 853 | 854 | ### Example 1: Simple → Adaptive Refinement 855 | 856 | **Before** (`refinement_step.md`): 857 | ```markdown 858 | # Refinement Step 859 | 860 | Refine this analysis: {{analysis}} 861 | 862 | Please improve the analysis based on validation feedback: {{validation_issues}} 863 | ``` 864 | 865 | **After**: 866 | ```nunjucks 867 | # Adaptive Refinement Step 868 | 869 | {% if validation_score < 0.6 %} 870 | ## 🔴 CRITICAL - COMPREHENSIVE REBUILD 871 | 872 | Validation Score: {{validation_score}} (Critical) 873 | 874 | ### Failed Criteria: 875 | {% for issue in validation_issues %} 876 | - {{issue.criterion}}: {{issue.reason}} 877 | **Required Action**: {{issue.remedy}} 878 | {% endfor %} 879 | 880 | ### Rebuild Protocol: 881 | 1. **Foundation Reset**: Restart analysis from core principles 882 | 2. **Systematic Remediation**: Address each failed criterion thoroughly 883 | 3. **Evidence Strengthening**: Add authoritative sources and citations 884 | 4. **Quality Verification**: Self-validate against all criteria before completion 885 | 886 | **Success Target**: Achieve validation score ≥ 0.75 with zero critical issues 887 | 888 | {% elif validation_score < 0.8 %} 889 | ## 🟡 MODERATE IMPROVEMENTS NEEDED 890 | 891 | Validation Score: {{validation_score}} (Needs Enhancement) 892 | 893 | ### Issues to Address: 894 | {% for issue in validation_issues %} 895 | - **{{issue.criterion}}**: {{issue.reason}} 896 | {% endfor %} 897 | 898 | ### Targeted Improvement Strategy: 899 | 1. Address each issue systematically 900 | 2. Enhance supporting evidence and examples 901 | 3. Clarify ambiguous sections 902 | 4. Strengthen logical flow and argumentation 903 | 904 | **Target**: Validation score ≥ 0.85 905 | 906 | {% else %} 907 | ## 🟢 EXCELLENT - FINAL POLISH 908 | 909 | Validation Score: {{validation_score}} (Excellent!) 910 | 911 | {% if validation_issues|length > 0 %} 912 | Minor refinements needed: 913 | {% for issue in validation_issues %} 914 | - {{issue.criterion}}: {{issue.reason}} 915 | {% endfor %} 916 | {% else %} 917 | No issues identified - apply publication polish only. 918 | {% endif %} 919 | 920 | ### Final Polish Checklist: 921 | - ✨ Optimize language precision and clarity 922 | - 📝 Ensure consistent terminology throughout 923 | - 🎨 Enhance visual formatting and readability 924 | - 🔍 Final proofreading pass 925 | 926 | {% endif %} 927 | 928 | --- 929 | 930 | **Original Analysis:** 931 | {{analysis}} 932 | 933 | **Instructions**: Apply refinements appropriate to the quality level indicated above. Focus on achieving target validation score with efficient, focused improvements. 934 | ``` 935 | 936 | **Impact**: 937 | - ✅ Appropriate effort based on quality 938 | - ✅ Specific, actionable instructions 939 | - ✅ Clear success criteria 940 | - ✅ Efficient resource utilization 941 | 942 | ### Example 2: Static → Content-Adaptive Format 943 | 944 | **Before** (`final_output.md`): 945 | ```markdown 946 | # Final Output 947 | 948 | Create final documentation from: {{content}} 949 | 950 | Target audience: {{audience}} 951 | ``` 952 | 953 | **After**: 954 | ```nunjucks 955 | # Content-Adaptive Final Output 956 | 957 | {% set content_characteristics = { 958 | 'has_code': 'def ' in content or 'function ' in content or 'class ' in content, 959 | 'has_data': 'metric' in content or 'statistics' in content or 'data' in content, 960 | 'has_narrative': 'story' in content or 'experience' in content or 'journey' in content, 961 | 'technical_level': step2_analysis.technical_level or 'medium' 962 | } %} 963 | 964 | ## Format Selection 965 | 966 | Content Type: 967 | {% if content_characteristics.has_code %}**Technical/Code-Heavy**{% endif %} 968 | {% if content_characteristics.has_data %}**Data/Analytical**{% endif %} 969 | {% if content_characteristics.has_narrative %}**Narrative/Story-Driven**{% endif %} 970 | 971 | Technical Level: {{content_characteristics.technical_level}} 972 | Target Audience: {{audience}} 973 | 974 | --- 975 | 976 | {% if content_characteristics.has_code and audience == 'developers' %} 977 | 978 | ## Technical Documentation Format 979 | 980 | Structure the final output as: 981 | 982 | ### Code Reference Documentation 983 | ``` 984 | [Language] [Function/Class Name] 985 | 986 | **Purpose**: [Clear description] 987 | 988 | **Parameters**: 989 | - param1 (type): description 990 | - param2 (type): description 991 | 992 | **Returns**: type and description 993 | 994 | **Example Usage**: 995 | ```[language] 996 | [working code example] 997 | ``` 998 | 999 | **Notes**: Implementation details, edge cases, performance considerations 1000 | ``` 1001 | 1002 | Apply this structure to all code elements in: {{content}} 1003 | 1004 | {% elif content_characteristics.has_data and audience in ['analysts', 'executives'] %} 1005 | 1006 | ## Analytical Report Format 1007 | 1008 | Structure as: 1009 | 1010 | ### Executive Summary 1011 | [2-3 sentence overview of key findings] 1012 | 1013 | ### Key Metrics 1014 | | Metric | Value | Trend | Implication | 1015 | |--------|-------|-------|-------------| 1016 | [tabular data presentation] 1017 | 1018 | ### Detailed Analysis 1019 | [Section for each major finding with supporting data] 1020 | 1021 | ### Recommendations 1022 | [Actionable insights prioritized by impact] 1023 | 1024 | {% elif content_characteristics.has_narrative or audience == 'general' %} 1025 | 1026 | ## Narrative Format 1027 | 1028 | Structure with: 1029 | 1030 | ### Introduction 1031 | [Engaging opening that sets context] 1032 | 1033 | ### Story Arc 1034 | [Progressive narrative with clear flow] 1035 | - Context setting 1036 | - Challenge/opportunity 1037 | - Actions taken 1038 | - Results and outcomes 1039 | - Lessons learned 1040 | 1041 | ### Conclusion 1042 | [Memorable takeaway] 1043 | 1044 | {% else %} 1045 | 1046 | ## Standard Documentation Format 1047 | 1048 | ### Overview 1049 | [High-level summary] 1050 | 1051 | ### Main Content 1052 | {{content}} 1053 | 1054 | ### Conclusion 1055 | [Key takeaways] 1056 | 1057 | {% endif %} 1058 | 1059 | --- 1060 | 1061 | **Source Content:** {{content}} 1062 | 1063 | **Instructions**: Apply the format structure indicated above, adapting the content appropriately for the target audience and content type. 1064 | ``` 1065 | 1066 | **Benefits**: 1067 | - ✅ Automatic format selection 1068 | - ✅ Audience-appropriate structure 1069 | - ✅ Content-type optimization 1070 | - ✅ Consistent quality across types 1071 | 1072 | --- 1073 | 1074 | ## Best Practices & Patterns 1075 | 1076 | ### 1. Progressive Instruction Clarity 1077 | 1078 | **Pattern**: Increase instruction specificity as quality decreases 1079 | 1080 | ```nunjucks 1081 | {% if quality_score > 0.9 %} 1082 | {# High quality: minimal, high-level guidance #} 1083 | Polish to perfection. 1084 | 1085 | {% elif quality_score > 0.7 %} 1086 | {# Good quality: structured guidance #} 1087 | 1. Address these specific issues: {{issues}} 1088 | 2. Enhance clarity in sections X, Y 1089 | 3. Validate completion 1090 | 1091 | {% else %} 1092 | {# Low quality: detailed step-by-step #} 1093 | Follow this detailed protocol: 1094 | 1095 | Step 1: Foundation Analysis 1096 | 1.1. Review core requirements: {{requirements}} 1097 | 1.2. Identify gaps in current version 1098 | 1.3. Document specific deficiencies 1099 | 1100 | Step 2: Systematic Remediation 1101 | 2.1. For each deficiency: 1102 | a) Root cause analysis 1103 | b) Evidence-based solution 1104 | c) Implementation 1105 | d) Validation 1106 | 1107 | Step 3: Quality Verification 1108 | [Detailed verification checklist] 1109 | {% endif %} 1110 | ``` 1111 | 1112 | ### 2. Error Context Preservation 1113 | 1114 | **Pattern**: Carry error context through recovery steps 1115 | 1116 | ```nunjucks 1117 | {% if previous_error %} 1118 | 1119 | ## Error Recovery Context 1120 | 1121 | **Original Error**: {{previous_error.message}} 1122 | **Failed Step**: {{previous_error.step_name}} 1123 | **Attempt Number**: {{previous_error.attempt_count}} 1124 | 1125 | {% if previous_error.attempt_count > 2 %} 1126 | **ALERT**: Multiple failures detected. Applying simplified approach. 1127 | {# Provide more guided, conservative instructions #} 1128 | {% else %} 1129 | **Retry Strategy**: Address specific error cause 1130 | {# Standard recovery #} 1131 | {% endif %} 1132 | 1133 | {% endif %} 1134 | ``` 1135 | 1136 | ### 3. Metric-Driven Branching 1137 | 1138 | **Pattern**: Use multiple metrics for nuanced decisions 1139 | 1140 | ```nunjucks 1141 | {% set needs_accuracy_work = accuracy_score < 0.8 %} 1142 | {% set needs_clarity_work = clarity_score < 0.8 %} 1143 | {% set needs_completeness_work = completeness_score < 0.8 %} 1144 | 1145 | {% if needs_accuracy_work and needs_clarity_work and needs_completeness_work %} 1146 | ## Comprehensive Improvement Required (All Areas) 1147 | [Instructions covering all three dimensions] 1148 | 1149 | {% elif needs_accuracy_work %} 1150 | ## Focus: Accuracy Enhancement 1151 | [Accuracy-specific instructions] 1152 | 1153 | {% elif needs_clarity_work %} 1154 | ## Focus: Clarity Improvement 1155 | [Clarity-specific instructions] 1156 | 1157 | {% elif needs_completeness_work %} 1158 | ## Focus: Completeness 1159 | [Completeness-specific instructions] 1160 | 1161 | {% else %} 1162 | ## Minor Polish Only 1163 | [Light refinement instructions] 1164 | {% endif %} 1165 | ``` 1166 | 1167 | ### 4. Accumulated State Patterns 1168 | 1169 | **Pattern**: Use state from multiple previous steps 1170 | 1171 | ```nunjucks 1172 | {# Step 4 references Steps 1, 2, and 3 #} 1173 | 1174 | {% set initial_complexity = step1_analysis.complexity_level %} 1175 | {% set research_depth = step2_research.source_count %} 1176 | {% set validation_passed = step3_validation.passed %} 1177 | 1178 | {% if initial_complexity > 7 and research_depth < 5 %} 1179 | 1180 | ## ⚠️ Complexity-Research Mismatch 1181 | 1182 | Analysis Complexity: {{initial_complexity}}/10 (High) 1183 | Research Depth: {{research_depth}} sources (Insufficient) 1184 | 1185 | **Action Required**: Expand research to match complexity 1186 | - Target: Minimum {{initial_complexity}} authoritative sources 1187 | - Diversify: Include academic, industry, and expert perspectives 1188 | 1189 | {% elif not validation_passed and research_depth > 10 %} 1190 | 1191 | ## ⚠️ Quality Issue Despite Deep Research 1192 | 1193 | Research Sources: {{research_depth}} (Extensive) 1194 | Validation: FAILED 1195 | 1196 | **Analysis**: Issue not lack of sources but synthesis quality 1197 | **Action**: Focus on integration and analysis, not more research 1198 | 1199 | {% endif %} 1200 | ``` 1201 | 1202 | ### 5. Self-Documenting Conditionals 1203 | 1204 | **Pattern**: Make template logic self-explanatory 1205 | 1206 | ```nunjucks 1207 | {# DECISION POINT: Determine refinement approach based on validation #} 1208 | {% set quality_threshold_critical = 0.6 %} 1209 | {% set quality_threshold_target = 0.8 %} 1210 | {% set requires_rebuild = validation_score < quality_threshold_critical %} 1211 | {% set requires_enhancement = validation_score < quality_threshold_target and not requires_rebuild %} 1212 | 1213 | {# BRANCH 1: Critical quality - rebuild from scratch #} 1214 | {% if requires_rebuild %} 1215 | ## Critical Quality Issues (Score: {{validation_score}}) 1216 | [Rebuild instructions] 1217 | 1218 | {# BRANCH 2: Moderate quality - targeted improvements #} 1219 | {% elif requires_enhancement %} 1220 | ## Enhancement Required (Score: {{validation_score}}) 1221 | [Enhancement instructions] 1222 | 1223 | {# BRANCH 3: Good quality - polish only #} 1224 | {% else %} 1225 | ## Excellent Quality (Score: {{validation_score}}) 1226 | [Polish instructions] 1227 | {% endif %} 1228 | ``` 1229 | 1230 | --- 1231 | 1232 | ## Performance Considerations 1233 | 1234 | ### Template Rendering Performance 1235 | 1236 | **Nunjucks Rendering Cost**: 1237 | - Variable substitution: ~1ms per 100 variables 1238 | - Simple conditionals: ~0.5ms per condition 1239 | - Loops: ~0.1ms per iteration 1240 | - Complex filters: ~1-5ms depending on operation 1241 | 1242 | **Optimization Strategies**: 1243 | 1244 | 1. **Cache Template Objects**: 1245 | ```typescript 1246 | // Already configured in jsonUtils.ts 1247 | const nunjucksEnv = nunjucks.configure(promptTemplatesPath, { 1248 | noCache: process.env.NODE_ENV === "development", // Cache in production 1249 | }); 1250 | ``` 1251 | 1252 | 2. **Minimize Loop Complexity**: 1253 | ```nunjucks 1254 | {# AVOID: Nested loops with complex operations #} 1255 | {% for item in large_list %} 1256 | {% for subitem in item.subitems %} 1257 | {{ subitem|complex_filter|another_filter }} 1258 | {% endfor %} 1259 | {% endfor %} 1260 | 1261 | {# PREFER: Pre-process in JavaScript, simple loops #} 1262 | {% for processed_item in preprocessed_list %} 1263 | {{ processed_item }} 1264 | {% endfor %} 1265 | ``` 1266 | 1267 | 3. **Conditional Short-Circuiting**: 1268 | ```nunjucks 1269 | {# AVOID: Multiple expensive checks #} 1270 | {% if expensive_check_1() and expensive_check_2() and expensive_check_3() %} 1271 | 1272 | {# PREFER: Check cheapest/most likely to fail first #} 1273 | {% if simple_check and moderate_check and expensive_check %} 1274 | ``` 1275 | 1276 | 4. **Variable Pre-Processing**: 1277 | ```typescript 1278 | // In chain executor, before template rendering: 1279 | const templateVars = { 1280 | ...stepOutputs, 1281 | // Pre-calculate expensive derived values 1282 | total_complexity: calculateComplexity(stepOutputs), 1283 | quality_level: determineQualityLevel(stepOutputs.validation_score), 1284 | }; 1285 | ``` 1286 | 1287 | ### Memory Considerations 1288 | 1289 | **Template Variable Memory**: 1290 | - Each step can accumulate outputs from all previous steps 1291 | - Long chains (>10 steps) can grow context significantly 1292 | - Monitor memory usage in long-running chains 1293 | 1294 | **Mitigation**: 1295 | ```typescript 1296 | // Prune unnecessary data before passing to next step 1297 | const prunedOutputs = { 1298 | // Keep only what next step needs 1299 | summary: stepOutput.summary, 1300 | quality_score: stepOutput.quality_score, 1301 | issues: stepOutput.issues, 1302 | // Omit large content that won't be used 1303 | // detailed_content: stepOutput.detailed_content, // Skip if not needed 1304 | }; 1305 | ``` 1306 | 1307 | --- 1308 | 1309 | ## Future Enhancements 1310 | 1311 | ### Phase 2: Dynamic Step Selection (Execution Engine) 1312 | 1313 | **Beyond Nunjucks Capability** - Requires execution engine changes: 1314 | 1315 | ```json 1316 | { 1317 | "steps": [ 1318 | {"id": "step1", "promptId": "analysis"}, 1319 | { 1320 | "id": "step2_conditional", 1321 | "conditionalBranch": { 1322 | "condition": "step1.quality_score < 0.7", 1323 | "ifTrue": {"promptId": "deep_analysis"}, 1324 | "ifFalse": {"promptId": "standard_refinement"} 1325 | } 1326 | } 1327 | ] 1328 | } 1329 | ``` 1330 | 1331 | ### Phase 3: Recursive Step Execution 1332 | 1333 | **Loop Until Quality Threshold**: 1334 | 1335 | ```json 1336 | { 1337 | "steps": [ 1338 | {"id": "initial", "promptId": "draft"}, 1339 | { 1340 | "id": "refine_loop", 1341 | "promptId": "refinement", 1342 | "loopCondition": { 1343 | "maxIterations": 3, 1344 | "exitWhen": "output.quality_score >= 0.8" 1345 | } 1346 | } 1347 | ] 1348 | } 1349 | ``` 1350 | 1351 | ### Phase 4: LLM-Driven Chain Orchestration 1352 | 1353 | **AI Decides Next Step**: 1354 | 1355 | ```typescript 1356 | // Execution engine asks LLM what to do next 1357 | const nextStepDecision = await llm.decide({ 1358 | prompt: "Based on these results, should we: A) Proceed to synthesis, B) Gather more research, C) Refine current analysis?", 1359 | context: currentStepOutputs, 1360 | options: ["synthesis", "research", "refinement"] 1361 | }); 1362 | ``` 1363 | 1364 | ### Phase 5: Quality Gate Integration 1365 | 1366 | **Automatic Quality Enforcement**: 1367 | 1368 | ```json 1369 | { 1370 | "steps": [ 1371 | {"id": "step1", "promptId": "analysis"}, 1372 | { 1373 | "id": "quality_gate", 1374 | "type": "validation", 1375 | "requirements": { 1376 | "minimum_quality_score": 0.8, 1377 | "required_fields": ["citations", "evidence"], 1378 | "failureAction": "retry_previous_step" 1379 | } 1380 | } 1381 | ] 1382 | } 1383 | ``` 1384 | 1385 | --- 1386 | 1387 | ## Implementation Checklist 1388 | 1389 | ### Week 1: Foundation 1390 | - [ ] Audit all existing chains 1391 | - [ ] Document current variable passing patterns 1392 | - [ ] Identify top 3 chains for enhancement 1393 | - [ ] Design adaptive pattern library 1394 | - [ ] Create Nunjucks filter helpers 1395 | 1396 | ### Week 2: Core Implementation 1397 | - [ ] Enhance quality validation steps with detailed metrics 1398 | - [ ] Transform 3 priority chains with adaptive templates 1399 | - [ ] Add quality-driven conditionals 1400 | - [ ] Implement complexity-based branching 1401 | 1402 | ### Week 3: Advanced Patterns 1403 | - [ ] Add error recovery patterns 1404 | - [ ] Implement content-type adaptation 1405 | - [ ] Create accumulated state patterns 1406 | - [ ] Build format selection logic 1407 | 1408 | ### Week 4: Testing & Documentation 1409 | - [ ] Test all adaptive chains with various inputs 1410 | - [ ] Validate conditional branches 1411 | - [ ] Document template patterns 1412 | - [ ] Create developer guide for adaptive prompts 1413 | 1414 | ### Week 5: Optimization 1415 | - [ ] Performance profiling 1416 | - [ ] Memory optimization 1417 | - [ ] Template caching validation 1418 | - [ ] Production readiness review 1419 | 1420 | --- 1421 | 1422 | ## Success Metrics 1423 | 1424 | ### Quantitative 1425 | - ✅ 5+ chains enhanced with adaptive templates 1426 | - ✅ 30%+ reduction in low-quality outputs requiring manual intervention 1427 | - ✅ Quality score improvement: average increase from 0.75 → 0.85+ 1428 | - ✅ Template rendering performance: <50ms per step 1429 | - ✅ Zero template rendering errors in production 1430 | 1431 | ### Qualitative 1432 | - ✅ Chains intelligently adapt to quality levels 1433 | - ✅ Error recovery is automatic and effective 1434 | - ✅ Resource utilization is efficient (effort matches need) 1435 | - ✅ Developer understanding of adaptive patterns is high 1436 | - ✅ Template maintenance is straightforward 1437 | 1438 | --- 1439 | 1440 | ## Conclusion 1441 | 1442 | **Key Insight**: Nunjucks templates in chain steps have access to all previous step results, enabling sophisticated result-based conditional logic and adaptive prompt instructions. 1443 | 1444 | **Strategic Value**: 1445 | - **Intelligent Adaptation**: Prompts adjust behavior based on quality, complexity, and errors 1446 | - **Resource Efficiency**: Apply appropriate effort based on actual needs 1447 | - **Quality Assurance**: Automatic escalation when quality thresholds not met 1448 | - **Error Resilience**: Graceful recovery from validation failures 1449 | 1450 | **Path Forward**: 1451 | 1. Enhance validation steps to output detailed quality metrics 1452 | 2. Transform existing chains with adaptive templates 1453 | 3. Build pattern library for common adaptation scenarios 1454 | 4. Extend to dynamic step selection in execution engine 1455 | 1456 | **Ultimate Goal**: Self-optimizing chain orchestration where each step intelligently adapts based on runtime results, maximizing quality while minimizing unnecessary computation. 1457 | 1458 | --- 1459 | 1460 | **Next Steps**: Begin Week 1 implementation with chain audit and pattern library design. 1461 | 1462 | **Document Maintainer**: Architecture Team 1463 | **Last Updated**: 2025-10-05 1464 | **Review Frequency**: Bi-weekly during implementation, monthly thereafter 1465 | ``` -------------------------------------------------------------------------------- /server/src/mcp-tools/index.ts: -------------------------------------------------------------------------------- ```typescript 1 | /** 2 | * MCP Tools Module - Consolidated Architecture 3 | * 4 | * This module provides 3 core MCP tools with framework-aware descriptions: 5 | * 6 | * CORE TOOLS: 7 | * - prompt_engine: Universal execution engine with framework integration 8 | * - prompt_manager: Complete prompt lifecycle management with intelligent filtering 9 | * - system_control: Framework and system management with analytics 10 | * 11 | * ARCHITECTURE: 12 | * - Framework-aware tool descriptions that change based on active methodology 13 | * - Single source of truth for each functional area 14 | * - Integrated ToolDescriptionManager for dynamic descriptions 15 | * - Improved maintainability and clear separation of concerns 16 | */ 17 | 18 | import { z } from "zod"; 19 | import { ConfigManager } from "../config/index.js"; 20 | import { Logger } from "../logging/index.js"; 21 | import { PromptManager } from "../prompts/index.js"; 22 | import { Category, ConvertedPrompt, PromptData } from "../types/index.js"; 23 | // Gate evaluator removed - now using Framework methodology validation 24 | import { 25 | FrameworkManager, 26 | createFrameworkManager, 27 | } from "../frameworks/framework-manager.js"; 28 | import { FrameworkStateManager } from "../frameworks/framework-state-manager.js"; 29 | import { createContentAnalyzer } from "../semantic/configurable-semantic-analyzer.js"; 30 | import { createSemanticIntegrationFactory } from "../semantic/integrations/index.js"; 31 | import { 32 | ConversationManager, 33 | createConversationManager, 34 | } from "../text-references/conversation.js"; 35 | import { 36 | TextReferenceManager, 37 | createTextReferenceManager, 38 | } from "../text-references/index.js"; 39 | // REMOVED: ExecutionCoordinator and ChainOrchestrator - modular chain system removed 40 | import { MetricsCollector, createMetricsCollector } from "../metrics/index.js"; 41 | 42 | // Consolidated tools 43 | import { 44 | ConsolidatedPromptEngine, 45 | createConsolidatedPromptEngine, 46 | } from "./prompt-engine/index.js"; 47 | import { 48 | ConsolidatedPromptManager, 49 | createConsolidatedPromptManager, 50 | } from "./prompt-manager/index.js"; 51 | import { 52 | ConsolidatedSystemControl, 53 | createConsolidatedSystemControl, 54 | } from "./system-control.js"; 55 | import { ToolDescriptionManager } from "./tool-description-manager.js"; 56 | // Gate system management integration 57 | import { 58 | GateSystemManager, 59 | createGateSystemManager, 60 | } from "../gates/gate-state-manager.js"; 61 | 62 | /** 63 | * Consolidated MCP Tools Manager 64 | * 65 | * Manages 3 intelligent consolidated tools that replace the previous 24+ scattered tools 66 | */ 67 | export class ConsolidatedMcpToolsManager { 68 | private logger: Logger; 69 | private mcpServer: any; 70 | private promptManager: PromptManager; 71 | private configManager: ConfigManager; 72 | 73 | // Consolidated tools (3 instead of 24+) 74 | private promptEngine!: ConsolidatedPromptEngine; 75 | private promptManagerTool!: ConsolidatedPromptManager; 76 | private systemControl!: ConsolidatedSystemControl; 77 | // Core tools: prompt engine, manager, and system control 78 | 79 | // Shared components 80 | private semanticAnalyzer!: ReturnType<typeof createContentAnalyzer>; 81 | private frameworkStateManager?: FrameworkStateManager; 82 | private frameworkManager?: FrameworkManager; 83 | // REMOVED: chainOrchestrator - modular chain system removed 84 | private conversationManager!: ConversationManager; 85 | private textReferenceManager!: TextReferenceManager; 86 | private toolDescriptionManager?: ToolDescriptionManager; 87 | private gateSystemManager?: GateSystemManager; 88 | private analyticsService!: MetricsCollector; 89 | // Phase 3: Removed executionCoordinator - chains now use LLM-driven execution model 90 | 91 | // Callback references 92 | private onRestart?: (reason: string) => Promise<void>; 93 | 94 | // Data references 95 | private promptsData: PromptData[] = []; 96 | private convertedPrompts: ConvertedPrompt[] = []; 97 | private categories: Category[] = []; 98 | 99 | // Pending analytics queue for initialization race condition 100 | private pendingAnalytics: any[] = []; 101 | 102 | constructor( 103 | logger: Logger, 104 | mcpServer: any, 105 | promptManager: PromptManager, 106 | configManager: ConfigManager 107 | // Phase 3: Removed executionCoordinator parameter - using LLM-driven chain model 108 | ) { 109 | this.logger = logger; 110 | this.mcpServer = mcpServer; 111 | this.promptManager = promptManager; 112 | this.configManager = configManager; 113 | // Phase 3: Removed executionCoordinator assignment - using LLM-driven chain model 114 | } 115 | 116 | /** 117 | * Initialize the MCP tools with async configuration 118 | */ 119 | async initialize( 120 | onRefresh: () => Promise<void>, 121 | onRestart: (reason: string) => Promise<void> 122 | ): Promise<void> { 123 | // Store callback references 124 | this.onRestart = onRestart; 125 | 126 | // Initialize shared components with configurable analysis 127 | const analysisConfig = this.configManager.getSemanticAnalysisConfig(); 128 | const integrationFactory = createSemanticIntegrationFactory(this.logger); 129 | this.semanticAnalyzer = await integrationFactory.createFromEnvironment( 130 | analysisConfig 131 | ); 132 | this.conversationManager = createConversationManager(this.logger); 133 | this.textReferenceManager = createTextReferenceManager(this.logger); 134 | this.analyticsService = createMetricsCollector(this.logger); 135 | 136 | // Initialize gate system manager for runtime gate control 137 | this.gateSystemManager = createGateSystemManager(this.logger, undefined); 138 | await this.gateSystemManager.initialize(); 139 | 140 | // Integrate text reference manager with conversation manager 141 | this.conversationManager.setTextReferenceManager(this.textReferenceManager); 142 | 143 | this.logger.info( 144 | `Configurable semantic analyzer initialized (mode: ${analysisConfig.mode})` 145 | ); 146 | 147 | // Initialize consolidated tools 148 | this.promptEngine = createConsolidatedPromptEngine( 149 | this.logger, 150 | this.mcpServer, 151 | this.promptManager, 152 | this.configManager, 153 | this.semanticAnalyzer, 154 | this.conversationManager, 155 | this.textReferenceManager, 156 | this // Pass manager reference for analytics data flow 157 | // Phase 3: Removed executionCoordinator - chains now use LLM-driven execution 158 | ); 159 | 160 | // Set gate system manager in prompt engine 161 | this.promptEngine.setGateSystemManager(this.gateSystemManager); 162 | 163 | this.promptManagerTool = createConsolidatedPromptManager( 164 | this.logger, 165 | this.mcpServer, 166 | this.configManager, 167 | this.semanticAnalyzer, 168 | this.frameworkStateManager, 169 | this.frameworkManager, 170 | onRefresh, 171 | onRestart 172 | ); 173 | 174 | // Initialize 3 core consolidated tools 175 | 176 | this.systemControl = createConsolidatedSystemControl( 177 | this.logger, 178 | this.mcpServer, 179 | onRestart 180 | ); 181 | 182 | // Set gate system manager in system control 183 | this.systemControl.setGateSystemManager(this.gateSystemManager); 184 | this.systemControl.setGateGuidanceRenderer( 185 | this.promptEngine.getGateGuidanceRenderer() 186 | ); 187 | 188 | // chainScaffolder removed - functionality consolidated into promptEngine 189 | 190 | // Flush any pending analytics data that was queued during initialization 191 | this.flushPendingAnalytics(); 192 | 193 | this.logger.info( 194 | "Consolidated MCP Tools Manager initialized with 3 intelligent tools (chain management in prompt_engine)" 195 | ); 196 | } 197 | 198 | /** 199 | * Set framework state manager (called after initialization) 200 | */ 201 | setFrameworkStateManager(frameworkStateManager: FrameworkStateManager): void { 202 | this.frameworkStateManager = frameworkStateManager; 203 | this.promptEngine.setFrameworkStateManager(frameworkStateManager); 204 | this.systemControl.setFrameworkStateManager(frameworkStateManager); 205 | this.promptManagerTool.setFrameworkStateManager?.(frameworkStateManager); 206 | // FIXED: Synchronize Framework Manager with Framework State Manager to prevent injection duplication 207 | if (this.frameworkManager) { 208 | this.frameworkManager.setFrameworkStateManager(frameworkStateManager); 209 | } 210 | // Core tools handle framework state integration 211 | } 212 | 213 | /** 214 | * Set tool description manager (called after initialization) 215 | */ 216 | setToolDescriptionManager(manager: ToolDescriptionManager): void { 217 | this.toolDescriptionManager = manager; 218 | 219 | this.promptEngine.setToolDescriptionManager(manager); 220 | this.promptEngine.setAnalyticsService(this.analyticsService); 221 | // promptManagerTool doesn't have setToolDescriptionManager method 222 | this.systemControl.setToolDescriptionManager?.(manager); 223 | this.systemControl.setAnalyticsService(this.analyticsService); 224 | // Core tools integrated with framework-aware descriptions 225 | 226 | // Set up hot-reload event listeners 227 | this.setupToolDescriptionHotReload(manager); 228 | 229 | this.logger.info( 230 | "Tool description manager set for all MCP tools with hot-reload support" 231 | ); 232 | } 233 | 234 | /** 235 | * Setup hot-reload event listeners for tool descriptions 236 | */ 237 | private setupToolDescriptionHotReload(manager: ToolDescriptionManager): void { 238 | // Listen for description changes 239 | manager.on("descriptions-changed", (stats) => { 240 | this.logger.info( 241 | `🔥 Tool descriptions hot-reloaded: ${stats.totalDescriptions} descriptions loaded` 242 | ); 243 | this.handleToolDescriptionChange(stats); 244 | }); 245 | 246 | // Listen for reload errors 247 | manager.on("descriptions-error", (error) => { 248 | this.logger.error( 249 | `❌ Tool description reload failed: ${ 250 | error instanceof Error ? error.message : String(error) 251 | }` 252 | ); 253 | }); 254 | 255 | // Start file watching if not already watching 256 | if (!manager.isWatchingFile()) { 257 | manager.startWatching(); 258 | } 259 | } 260 | 261 | /** 262 | * Handle tool description changes 263 | */ 264 | private async handleToolDescriptionChange(stats: any): Promise<void> { 265 | try { 266 | this.logger.info("🔄 Processing tool description changes..."); 267 | 268 | // Emit analytics update 269 | this.updateAnalytics({ 270 | toolDescriptions: { 271 | lastReload: new Date().toISOString(), 272 | totalDescriptions: stats.totalDescriptions, 273 | loadedFromFile: stats.loadedFromFile, 274 | usingDefaults: stats.usingDefaults, 275 | }, 276 | }); 277 | 278 | // Note: MCP SDK doesn't support dynamic tool updates 279 | // The new descriptions will be loaded on next tool registration or server restart 280 | this.logger.info("✅ Tool descriptions reloaded from file"); 281 | this.logger.info( 282 | `📊 Stats: ${stats.totalDescriptions} total, using ${ 283 | stats.usingDefaults > 0 ? "defaults" : "external config" 284 | }` 285 | ); 286 | 287 | // Check if restart is configured for tool description changes 288 | const restartOnChange = 289 | this.configManager.getConfig().toolDescriptions?.restartOnChange ?? 290 | false; 291 | 292 | if (restartOnChange) { 293 | this.logger.info( 294 | "🚨 Restart on tool description change is enabled - initiating server restart..." 295 | ); 296 | // Use the existing restart mechanism 297 | await this.onRestart?.( 298 | "Tool descriptions updated - restart required for clients to see new descriptions" 299 | ); 300 | } else { 301 | this.logger.info( 302 | "💡 Tip: New tool descriptions will be used for new client connections. For immediate effect, restart the server manually or enable 'restartOnChange' in config." 303 | ); 304 | } 305 | } catch (error) { 306 | this.logger.error( 307 | `Failed to handle tool description change: ${ 308 | error instanceof Error ? error.message : String(error) 309 | }` 310 | ); 311 | } 312 | } 313 | 314 | /** 315 | * Initialize and set framework manager (called after framework state manager) 316 | */ 317 | async setFrameworkManager( 318 | existingFrameworkManager?: FrameworkManager 319 | ): Promise<void> { 320 | if (!this.frameworkManager) { 321 | // Use provided framework manager or create a new one 322 | this.frameworkManager = 323 | existingFrameworkManager || (await createFrameworkManager(this.logger)); 324 | this.promptEngine.setFrameworkManager(this.frameworkManager); 325 | this.systemControl.setFrameworkManager(this.frameworkManager); 326 | this.promptManagerTool.setFrameworkManager?.(this.frameworkManager); 327 | // Core tools integrated with framework management 328 | 329 | // Set ConfigManager for system control config operations 330 | this.systemControl.setConfigManager(this.configManager); 331 | 332 | // Set MCPToolsManager reference for dynamic tool updates 333 | this.systemControl.setMCPToolsManager(this); 334 | 335 | // Enhanced tool delegation removed (Phase 1.2) 336 | // Using core tools directly without delegation patterns 337 | 338 | // REMOVED: ChainOrchestrator initialization - modular chain system removed 339 | 340 | if (existingFrameworkManager) { 341 | this.logger.info( 342 | "Framework manager integrated with MCP tools (shared instance)" 343 | ); 344 | } else { 345 | this.logger.info( 346 | "Framework manager initialized and integrated with MCP tools" 347 | ); 348 | } 349 | } 350 | } 351 | 352 | // REMOVED: wireExecutionCoordinator - ExecutionCoordinator removed 353 | 354 | /** 355 | * Register all consolidated MCP tools with the server (centralized registration) 356 | */ 357 | async registerAllTools(): Promise<void> { 358 | this.logger.info( 359 | "Registering consolidated MCP tools with server (centralized)..." 360 | ); 361 | 362 | // Get current framework state for dynamic descriptions 363 | const frameworkEnabled = 364 | this.frameworkStateManager?.isFrameworkSystemEnabled() ?? false; 365 | const activeFramework = this.frameworkStateManager?.getActiveFramework(); 366 | const activeMethodology = 367 | activeFramework?.methodology ?? activeFramework?.id; 368 | 369 | this.logger.info(`🔧 Registering tools with framework-aware descriptions:`); 370 | this.logger.info(` Framework enabled: ${frameworkEnabled}`); 371 | this.logger.info(` Active framework: ${activeFramework?.id || "none"}`); 372 | this.logger.info(` Active methodology: ${activeMethodology || "none"}`); 373 | this.logger.info( 374 | ` Tool description manager: ${ 375 | this.toolDescriptionManager ? "available" : "not available" 376 | }` 377 | ); 378 | 379 | // Register prompt_engine tool 380 | try { 381 | // Get dynamic description based on current framework state 382 | const promptEngineDescription = 383 | this.toolDescriptionManager?.getDescription( 384 | "prompt_engine", 385 | frameworkEnabled, 386 | activeMethodology, 387 | { applyMethodologyOverride: true } 388 | ) ?? 389 | "🚀 PROMPT ENGINE [HOT-RELOAD]: Processes Nunjucks templates, returns executable instructions. WARNING: Output contains instructions YOU must execute (code gen, analysis, multi-step tasks) - not just information. IMPORTANT: When your arguments include newlines or structured blocks, wrap the call in JSON so the parser receives a single-line command shell."; 390 | 391 | const getPromptEngineParamDescription = ( 392 | paramName: string, 393 | fallback: string 394 | ) => 395 | this.toolDescriptionManager?.getParameterDescription( 396 | "prompt_engine", 397 | paramName, 398 | frameworkEnabled, 399 | activeMethodology, 400 | { applyMethodologyOverride: true } 401 | ) ?? fallback; 402 | 403 | // Log which description source is being used for transparency 404 | if (this.toolDescriptionManager) { 405 | this.logger.info( 406 | ` prompt_engine: Using ToolDescriptionManager (framework: ${frameworkEnabled}, methodology: ${activeMethodology})` 407 | ); 408 | } else { 409 | this.logger.info( 410 | ` prompt_engine: Using fallback description (ToolDescriptionManager not available)` 411 | ); 412 | } 413 | 414 | this.mcpServer.registerTool( 415 | "prompt_engine", 416 | { 417 | title: "Prompt Engine", 418 | description: promptEngineDescription, 419 | inputSchema: { 420 | command: z 421 | .string() 422 | .min(1, "Command cannot be empty") 423 | .describe( 424 | getPromptEngineParamDescription( 425 | "command", 426 | "Prompt name and arguments to process. WARNING: Will return instructions for YOU to execute, not just information. SIMPLE: >>prompt_name content (single-line arguments only). MULTI-LINE / RICH FORMATTING: {\\\"command\\\": \\\" >>prompt_name\\\", \\\"args\\\":{...}} keeps payload intact. ADVANCED: JSON with execution options" 427 | ) 428 | ), 429 | execution_mode: z 430 | .enum(["auto", "prompt", "template", "chain"]) 431 | .optional() 432 | .describe( 433 | getPromptEngineParamDescription( 434 | "execution_mode", 435 | "Override intelligent auto-detection (default: auto). 'auto' intelligently detects execution type, 'prompt' for single execution, 'template' for variable substitution, 'chain' for multi-step workflows" 436 | ) 437 | ), 438 | gate_validation: z 439 | .boolean() 440 | .optional() 441 | .describe( 442 | getPromptEngineParamDescription( 443 | "gate_validation", 444 | "Quality gate validation (MANDATORY for chains, auto-detected by default, see metadata sections for gate details)" 445 | ) 446 | ), 447 | step_confirmation: z 448 | .boolean() 449 | .optional() 450 | .describe( 451 | getPromptEngineParamDescription( 452 | "step_confirmation", 453 | "Require confirmation between chain steps" 454 | ) 455 | ), 456 | llm_driven_execution: z 457 | .boolean() 458 | .optional() 459 | .describe( 460 | getPromptEngineParamDescription( 461 | "llm_driven_execution", 462 | "Enable LLM-driven chain step coordination (requires semantic LLM integration)" 463 | ) 464 | ), 465 | force_restart: z 466 | .boolean() 467 | .optional() 468 | .describe( 469 | getPromptEngineParamDescription( 470 | "force_restart", 471 | "Force restart chain from beginning, clearing all existing state" 472 | ) 473 | ), 474 | session_id: z 475 | .string() 476 | .min(1, "Session ID cannot be empty if provided") 477 | .regex( 478 | /^[a-zA-Z0-9_-]+$/, 479 | "Session ID must contain only alphanumeric characters, underscores, and hyphens" 480 | ) 481 | .optional() 482 | .describe( 483 | getPromptEngineParamDescription( 484 | "session_id", 485 | "Specific session ID to use or resume" 486 | ) 487 | ), 488 | chain_uri: z 489 | .string() 490 | .optional() 491 | .describe( 492 | getPromptEngineParamDescription( 493 | "chain_uri", 494 | "Full chain URI for precise session control (e.g., chain://research_pipeline/session-abc123?force_restart=true)" 495 | ) 496 | ), 497 | timeout: z 498 | .number() 499 | .int() 500 | .positive() 501 | .optional() 502 | .describe( 503 | getPromptEngineParamDescription( 504 | "timeout", 505 | "Execution timeout in milliseconds" 506 | ) 507 | ), 508 | options: z 509 | .record(z.any()) 510 | .optional() 511 | .describe( 512 | getPromptEngineParamDescription( 513 | "options", 514 | "Additional execution options (key-value pairs). Supports framework-specific flags, debugging controls, and experimental features" 515 | ) 516 | ), 517 | }, 518 | }, 519 | async (args: { 520 | command: string; 521 | execution_mode?: "auto" | "prompt" | "template" | "chain"; 522 | gate_validation?: boolean; 523 | step_confirmation?: boolean; 524 | llm_driven_execution?: boolean; 525 | force_restart?: boolean; 526 | session_id?: string; 527 | chain_uri?: string; 528 | timeout?: number; 529 | options?: Record<string, any>; 530 | }) => { 531 | try { 532 | const toolResponse = await this.promptEngine.executePromptCommand( 533 | args, 534 | {} 535 | ); 536 | return { 537 | content: toolResponse.content, 538 | isError: toolResponse.isError, 539 | ...(toolResponse.structuredContent && { 540 | structuredContent: toolResponse.structuredContent, 541 | }), 542 | }; 543 | } catch (error) { 544 | this.logger.error( 545 | `prompt_engine error: ${ 546 | error instanceof Error ? error.message : String(error) 547 | }` 548 | ); 549 | return { 550 | content: [ 551 | { 552 | type: "text", 553 | text: `Error: ${ 554 | error instanceof Error ? error.message : String(error) 555 | }`, 556 | }, 557 | ], 558 | isError: true, 559 | }; 560 | } 561 | } 562 | ); 563 | this.logger.debug("✅ prompt_engine tool registered successfully"); 564 | } catch (error) { 565 | this.logger.error( 566 | `❌ Failed to register prompt_engine tool: ${ 567 | error instanceof Error ? error.message : String(error) 568 | }` 569 | ); 570 | throw error; 571 | } 572 | 573 | // Register prompt_manager tool 574 | try { 575 | // Get dynamic description based on current framework state 576 | const promptManagerDescription = 577 | this.toolDescriptionManager?.getDescription( 578 | "prompt_manager", 579 | frameworkEnabled, 580 | activeMethodology, 581 | { applyMethodologyOverride: true } 582 | ) ?? 583 | "🧰 PROMPT MANAGER: Create, update, delete, list, and analyze prompts. Supports gate configuration, temporary gates, and prompt-type migration."; 584 | 585 | const getPromptManagerParamDescription = ( 586 | paramName: string, 587 | fallback: string 588 | ) => 589 | this.toolDescriptionManager?.getParameterDescription( 590 | "prompt_manager", 591 | paramName, 592 | frameworkEnabled, 593 | activeMethodology, 594 | { applyMethodologyOverride: true } 595 | ) ?? fallback; 596 | 597 | // Log which description source is being used for transparency 598 | if (this.toolDescriptionManager) { 599 | this.logger.info( 600 | ` prompt_manager: Using ToolDescriptionManager (framework: ${frameworkEnabled}, methodology: ${activeMethodology})` 601 | ); 602 | } else { 603 | this.logger.info( 604 | ` prompt_manager: Using fallback description (ToolDescriptionManager not available)` 605 | ); 606 | } 607 | 608 | this.mcpServer.registerTool( 609 | "prompt_manager", 610 | { 611 | title: "Prompt Manager", 612 | description: promptManagerDescription, 613 | inputSchema: { 614 | action: z 615 | .enum([ 616 | "create", 617 | "create_prompt", 618 | "create_template", 619 | "analyze_type", 620 | "migrate_type", 621 | "update", 622 | "delete", 623 | "modify", 624 | "reload", 625 | "list", 626 | "analyze_gates", 627 | "suggest_temporary_gates", 628 | "create_with_gates", 629 | "update_gates", 630 | "add_temporary_gates", 631 | ]) 632 | .describe( 633 | getPromptManagerParamDescription( 634 | "action", 635 | "Action to perform. Supported: create, create_prompt, create_template, create_with_gates, update, delete, modify, reload, list, analyze_type, migrate_type, analyze_gates, update_gates, add_temporary_gates, suggest_temporary_gates." 636 | ) 637 | ), 638 | id: z 639 | .string() 640 | .optional() 641 | .describe( 642 | getPromptManagerParamDescription( 643 | "id", 644 | "Prompt identifier. Required for create*, update, delete, modify, analyze_type, migrate_type, analyze_gates, update_gates, add_temporary_gates. Use letters, numbers, underscores, or hyphens." 645 | ) 646 | ), 647 | name: z 648 | .string() 649 | .optional() 650 | .describe( 651 | getPromptManagerParamDescription( 652 | "name", 653 | "Friendly prompt name. Required for create*, create_with_gates." 654 | ) 655 | ), 656 | description: z 657 | .string() 658 | .optional() 659 | .describe( 660 | getPromptManagerParamDescription( 661 | "description", 662 | "Short description of the prompt purpose. Required for create*, create_with_gates." 663 | ) 664 | ), 665 | user_message_template: z 666 | .string() 667 | .optional() 668 | .describe( 669 | getPromptManagerParamDescription( 670 | "user_message_template", 671 | "Prompt body with Nunjucks placeholders (e.g. 'Analyze {{input}}'). Required for create*, create_with_gates." 672 | ) 673 | ), 674 | system_message: z 675 | .string() 676 | .optional() 677 | .describe( 678 | getPromptManagerParamDescription( 679 | "system_message", 680 | "Optional system message to store with the prompt." 681 | ) 682 | ), 683 | content: z 684 | .string() 685 | .optional() 686 | .describe( 687 | getPromptManagerParamDescription( 688 | "content", 689 | "Full prompt content for create/update operations when not using templates." 690 | ) 691 | ), 692 | category: z 693 | .string() 694 | .optional() 695 | .describe( 696 | getPromptManagerParamDescription( 697 | "category", 698 | "Category label used for filtering and organization." 699 | ) 700 | ), 701 | arguments: z 702 | .array( 703 | z.object({ 704 | name: z.string(), 705 | type: z.string(), 706 | description: z.string(), 707 | }) 708 | ) 709 | .optional() 710 | .describe( 711 | getPromptManagerParamDescription( 712 | "arguments", 713 | "Array of argument definitions ({name, type, description}) for prompts with structured inputs." 714 | ) 715 | ), 716 | suggested_gates: z 717 | .array( 718 | z.object({ 719 | type: z.enum(['validation', 'quality', 'approval', 'condition', 'guidance']), 720 | name: z.string(), 721 | description: z.string(), 722 | criteria: z.array(z.string()).optional(), 723 | }) 724 | ) 725 | .optional() 726 | .describe( 727 | getPromptManagerParamDescription( 728 | "suggested_gates", 729 | "Gate suggestions used by create_with_gates. Each entry should include type, name, description, and optional criteria." 730 | ) 731 | ), 732 | gate_configuration: z 733 | .object({ 734 | include: z.array(z.string()).optional(), 735 | exclude: z.array(z.string()).optional(), 736 | temporary_gates: z.array(z.any()).optional(), 737 | framework_gates: z.boolean().optional(), 738 | }) 739 | .optional() 740 | .describe( 741 | getPromptManagerParamDescription( 742 | "gate_configuration", 743 | "Explicit gate configuration (include/exclude lists, temporary gates, framework_gates flag)." 744 | ) 745 | ), 746 | temporary_gates: z 747 | .array(z.any()) 748 | .optional() 749 | .describe( 750 | getPromptManagerParamDescription( 751 | "temporary_gates", 752 | "Temporary gate definitions used by add_temporary_gates (include name, type, scope, description, guidance, pass_criteria)." 753 | ) 754 | ), 755 | gate_scope: z 756 | .enum(['execution', 'session', 'chain', 'step']) 757 | .optional() 758 | .describe( 759 | getPromptManagerParamDescription( 760 | "gate_scope", 761 | "Scope for temporary gates (execution, session, chain, step)." 762 | ) 763 | ), 764 | inherit_chain_gates: z 765 | .boolean() 766 | .optional() 767 | .describe( 768 | getPromptManagerParamDescription( 769 | "inherit_chain_gates", 770 | "When true, inherit gates from the parent chain (default true for add_temporary_gates)." 771 | ) 772 | ), 773 | search_query: z 774 | .string() 775 | .optional() 776 | .describe( 777 | getPromptManagerParamDescription( 778 | "search_query", 779 | "Search expression for list (e.g. 'category:code type:chain')." 780 | ) 781 | ), 782 | force: z 783 | .boolean() 784 | .optional() 785 | .describe( 786 | getPromptManagerParamDescription( 787 | "force", 788 | "Bypass confirmation prompts for supported actions." 789 | ) 790 | ), 791 | }, 792 | }, 793 | async (args: { 794 | action: 795 | | "create" 796 | | "create_prompt" 797 | | "create_template" 798 | | "analyze_type" 799 | | "migrate_type" 800 | | "update" 801 | | "delete" 802 | | "modify" 803 | | "reload" 804 | | "list" 805 | | "analyze_gates" 806 | | "suggest_temporary_gates" 807 | | "create_with_gates" 808 | | "update_gates" 809 | | "add_temporary_gates"; 810 | [key: string]: any; 811 | }) => { 812 | try { 813 | // Check if promptManagerTool exists 814 | if (!this.promptManagerTool) { 815 | this.logger.error(`ERROR: promptManagerTool is undefined!`); 816 | return { 817 | content: [ 818 | { 819 | type: "text", 820 | text: `Error: promptManagerTool is not initialized`, 821 | }, 822 | ], 823 | isError: true, 824 | }; 825 | } 826 | 827 | // CRITICAL: Adding error-level logging to trace MCP tool invocation 828 | this.logger.error(`[GATE-TRACE] 🔥 MCP TOOL INVOCATION: About to call promptManagerTool.handleAction for action: ${args.action}`); 829 | this.logger.error(`[GATE-TRACE] 🔥 MCP args being passed:`, args); 830 | 831 | const toolResponse = await this.promptManagerTool.handleAction( 832 | args, 833 | {} 834 | ); 835 | 836 | this.logger.error(`[GATE-TRACE] 🔥 MCP TOOL RESPONSE: handleAction completed for action: ${args.action}`); 837 | 838 | // Debug logging and validation 839 | if (!toolResponse) { 840 | this.logger.error( 841 | `prompt_manager returned undefined response for action: ${args.action}` 842 | ); 843 | return { 844 | content: [ 845 | { 846 | type: "text", 847 | text: `Error: Tool returned undefined response`, 848 | }, 849 | ], 850 | isError: true, 851 | }; 852 | } 853 | 854 | if (!toolResponse.content) { 855 | this.logger.error( 856 | `prompt_manager returned response with undefined content for action: ${args.action}`, 857 | toolResponse 858 | ); 859 | return { 860 | content: [ 861 | { 862 | type: "text", 863 | text: `Error: Tool returned response with undefined content`, 864 | }, 865 | ], 866 | isError: true, 867 | }; 868 | } 869 | 870 | return { 871 | content: toolResponse.content, 872 | isError: toolResponse.isError, 873 | ...(toolResponse.structuredContent && { 874 | structuredContent: toolResponse.structuredContent, 875 | }), 876 | }; 877 | } catch (error) { 878 | this.logger.error( 879 | `prompt_manager error: ${ 880 | error instanceof Error ? error.message : String(error) 881 | }` 882 | ); 883 | return { 884 | content: [ 885 | { 886 | type: "text", 887 | text: `Error: ${ 888 | error instanceof Error ? error.message : String(error) 889 | }`, 890 | }, 891 | ], 892 | isError: true, 893 | }; 894 | } 895 | } 896 | ); 897 | this.logger.debug("✅ prompt_manager tool registered successfully"); 898 | } catch (error) { 899 | this.logger.error( 900 | `❌ Failed to register prompt_manager tool: ${ 901 | error instanceof Error ? error.message : String(error) 902 | }` 903 | ); 904 | throw error; 905 | } 906 | 907 | // Register system_control tool 908 | try { 909 | // Get dynamic description based on current framework state 910 | const systemControlDescription = 911 | this.toolDescriptionManager?.getDescription( 912 | "system_control", 913 | frameworkEnabled, 914 | activeMethodology, 915 | { applyMethodologyOverride: true } 916 | ) ?? 917 | "⚙️ SYSTEM CONTROL: Unified interface for status, framework controls, gate management, analytics, configuration, and maintenance actions."; 918 | 919 | // Log which description source is being used for transparency 920 | if (this.toolDescriptionManager) { 921 | this.logger.info( 922 | ` system_control: Using ToolDescriptionManager (framework: ${frameworkEnabled}, methodology: ${activeMethodology})` 923 | ); 924 | } else { 925 | this.logger.info( 926 | ` system_control: Using fallback description (ToolDescriptionManager not available)` 927 | ); 928 | } 929 | 930 | const getSystemControlParamDescription = ( 931 | paramName: string, 932 | fallback: string 933 | ) => 934 | this.toolDescriptionManager?.getParameterDescription( 935 | "system_control", 936 | paramName, 937 | frameworkEnabled, 938 | activeMethodology, 939 | { applyMethodologyOverride: true } 940 | ) ?? fallback; 941 | 942 | this.mcpServer.registerTool( 943 | "system_control", 944 | { 945 | title: "System Control", 946 | description: systemControlDescription, 947 | inputSchema: { 948 | action: z 949 | .string() 950 | .describe( 951 | getSystemControlParamDescription( 952 | "action", 953 | "Top-level command. Supported values: status, framework, gates, analytics, config, maintenance." 954 | ) 955 | ), 956 | operation: z 957 | .string() 958 | .optional() 959 | .describe( 960 | getSystemControlParamDescription( 961 | "operation", 962 | "Sub-command for the selected action (e.g. framework: switch|list|enable|disable, analytics: view|reset|history)." 963 | ) 964 | ), 965 | framework: z 966 | .string() 967 | .optional() 968 | .describe( 969 | getSystemControlParamDescription( 970 | "framework", 971 | "Framework identifier when switching (CAGEERF, ReACT, 5W1H, SCAMPER)." 972 | ) 973 | ), 974 | config_path: z 975 | .string() 976 | .optional() 977 | .describe( 978 | getSystemControlParamDescription( 979 | "config_path", 980 | "Configuration path or key for config operations." 981 | ) 982 | ), 983 | config_value: z 984 | .any() 985 | .optional() 986 | .describe( 987 | getSystemControlParamDescription( 988 | "config_value", 989 | "Value to write when performing config updates." 990 | ) 991 | ), 992 | restart_reason: z 993 | .string() 994 | .optional() 995 | .describe( 996 | getSystemControlParamDescription( 997 | "restart_reason", 998 | "Specific reason recorded for maintenance/restart operations." 999 | ) 1000 | ), 1001 | reason: z 1002 | .string() 1003 | .optional() 1004 | .describe( 1005 | getSystemControlParamDescription( 1006 | "reason", 1007 | "Audit-friendly explanation for switches, config changes, or restarts." 1008 | ) 1009 | ), 1010 | include_history: z 1011 | .boolean() 1012 | .optional() 1013 | .describe( 1014 | getSystemControlParamDescription( 1015 | "include_history", 1016 | "Include historical entries (where supported)." 1017 | ) 1018 | ), 1019 | include_metrics: z 1020 | .boolean() 1021 | .optional() 1022 | .describe( 1023 | getSystemControlParamDescription( 1024 | "include_metrics", 1025 | "Include detailed metrics output (where supported)." 1026 | ) 1027 | ), 1028 | show_details: z 1029 | .boolean() 1030 | .optional() 1031 | .describe( 1032 | getSystemControlParamDescription( 1033 | "show_details", 1034 | "Request an expanded response for list/status style commands." 1035 | ) 1036 | ), 1037 | }, 1038 | }, 1039 | async (args: { action: string; [key: string]: any }) => { 1040 | try { 1041 | const toolResponse = await this.systemControl.handleAction( 1042 | args, 1043 | {} 1044 | ); 1045 | return { 1046 | content: toolResponse.content, 1047 | isError: toolResponse.isError, 1048 | ...(toolResponse.structuredContent && { 1049 | structuredContent: toolResponse.structuredContent, 1050 | }), 1051 | }; 1052 | } catch (error) { 1053 | this.logger.error( 1054 | `system_control error: ${ 1055 | error instanceof Error ? error.message : String(error) 1056 | }` 1057 | ); 1058 | return { 1059 | content: [ 1060 | { 1061 | type: "text", 1062 | text: `Error: ${ 1063 | error instanceof Error ? error.message : String(error) 1064 | }`, 1065 | }, 1066 | ], 1067 | isError: true, 1068 | }; 1069 | } 1070 | } 1071 | ); 1072 | this.logger.debug("✅ system_control tool registered successfully"); 1073 | } catch (error) { 1074 | this.logger.error( 1075 | `❌ Failed to register system_control tool: ${ 1076 | error instanceof Error ? error.message : String(error) 1077 | }` 1078 | ); 1079 | throw error; 1080 | } 1081 | this.logger.info("🎉 Centralized MCP tools registered successfully!"); 1082 | this.logger.info("📊 Core Tools: 3 centrally managed tools"); 1083 | this.logger.info( 1084 | "🚀 Active Tools: prompt_engine, prompt_manager, system_control" 1085 | ); 1086 | 1087 | // Log available tools for user reference 1088 | const toolSummary = [ 1089 | "Available Core Tools (centralized registration):", 1090 | "🎯 prompt_engine - Centralized prompt execution engine", 1091 | "🎯 prompt_manager - Centralized prompt lifecycle management", 1092 | "⚙️ system_control - Centralized framework and system management", 1093 | ].join("\n "); 1094 | 1095 | this.logger.info(toolSummary); 1096 | } 1097 | 1098 | /** 1099 | * Re-register all tools with updated descriptions (for framework switching) - centralized version 1100 | */ 1101 | async reregisterToolsWithUpdatedDescriptions(): Promise<void> { 1102 | this.logger.info( 1103 | "🔄 Re-registering tools with updated framework-aware descriptions..." 1104 | ); 1105 | 1106 | try { 1107 | // Simply call the centralized registration method which now uses dynamic descriptions 1108 | await this.registerAllTools(); 1109 | 1110 | // Notify MCP clients that tool list has changed 1111 | if (this.mcpServer?.server?.sendToolListChanged) { 1112 | await this.mcpServer.server.sendToolListChanged(); 1113 | this.logger.info( 1114 | "✅ Sent tool list changed notification to MCP clients" 1115 | ); 1116 | } else { 1117 | this.logger.warn( 1118 | "⚠️ MCP server does not support sendToolListChanged notification" 1119 | ); 1120 | } 1121 | 1122 | this.logger.info( 1123 | "🎉 Tools re-registered successfully with updated descriptions (centralized)!" 1124 | ); 1125 | } catch (error) { 1126 | this.logger.error( 1127 | `Failed to re-register tools: ${ 1128 | error instanceof Error ? error.message : String(error) 1129 | }` 1130 | ); 1131 | throw error; 1132 | } 1133 | } 1134 | 1135 | /** 1136 | * Update internal data references 1137 | */ 1138 | updateData( 1139 | promptsData: PromptData[], 1140 | convertedPrompts: ConvertedPrompt[], 1141 | categories: Category[] 1142 | ): void { 1143 | this.promptsData = promptsData; 1144 | this.convertedPrompts = convertedPrompts; 1145 | this.categories = categories; 1146 | 1147 | // Update all consolidated tools with new data 1148 | this.promptEngine.updateData(promptsData, convertedPrompts); 1149 | this.promptManagerTool.updateData( 1150 | promptsData, 1151 | convertedPrompts, 1152 | categories 1153 | ); 1154 | // Core tools handle data updates directly 1155 | } 1156 | 1157 | /** 1158 | * Update system analytics (from consolidated tools) 1159 | */ 1160 | updateAnalytics(analytics: any): void { 1161 | if (this.systemControl) { 1162 | this.systemControl.updateAnalytics(analytics); 1163 | } else { 1164 | // Queue analytics data until systemControl is initialized 1165 | this.pendingAnalytics.push(analytics); 1166 | this.logger.debug( 1167 | `SystemControl not yet initialized, queued analytics data (${this.pendingAnalytics.length} pending)` 1168 | ); 1169 | } 1170 | } 1171 | 1172 | /** 1173 | * Flush pending analytics data to systemControl after initialization 1174 | */ 1175 | private flushPendingAnalytics(): void { 1176 | if (this.systemControl && this.pendingAnalytics.length > 0) { 1177 | this.logger.debug( 1178 | `Flushing ${this.pendingAnalytics.length} pending analytics updates` 1179 | ); 1180 | this.pendingAnalytics.forEach((analytics) => { 1181 | this.systemControl.updateAnalytics(analytics); 1182 | }); 1183 | this.pendingAnalytics = []; 1184 | } 1185 | } 1186 | 1187 | /** 1188 | * Shutdown all components and cleanup resources 1189 | */ 1190 | shutdown(): void { 1191 | this.logger.info("🛑 Shutting down MCP tools manager..."); 1192 | 1193 | // Shutdown tool description manager and stop file watching 1194 | if (this.toolDescriptionManager) { 1195 | this.toolDescriptionManager.shutdown(); 1196 | this.logger.info("✅ Tool description manager shut down"); 1197 | } 1198 | 1199 | // Cleanup gate system manager 1200 | if (this.gateSystemManager) { 1201 | this.gateSystemManager.cleanup().catch((error) => { 1202 | this.logger.error("Error during gate system manager cleanup:", error); 1203 | }); 1204 | this.logger.info("✅ Gate system manager cleanup initiated"); 1205 | } 1206 | 1207 | // Clear pending analytics 1208 | this.pendingAnalytics = []; 1209 | 1210 | this.logger.info("✅ MCP tools manager shutdown completed"); 1211 | } 1212 | } 1213 | 1214 | /** 1215 | * Create consolidated MCP tools manager 1216 | */ 1217 | export async function createConsolidatedMcpToolsManager( 1218 | logger: Logger, 1219 | mcpServer: any, 1220 | promptManager: PromptManager, 1221 | configManager: ConfigManager, 1222 | onRefresh: () => Promise<void>, 1223 | onRestart: (reason: string) => Promise<void> 1224 | // Phase 3: Removed executionCoordinator parameter - using LLM-driven chain model 1225 | ): Promise<ConsolidatedMcpToolsManager> { 1226 | const manager = new ConsolidatedMcpToolsManager( 1227 | logger, 1228 | mcpServer, 1229 | promptManager, 1230 | configManager 1231 | // Phase 3: Removed executionCoordinator parameter 1232 | ); 1233 | 1234 | await manager.initialize(onRefresh, onRestart); 1235 | return manager; 1236 | } 1237 | 1238 | // Legacy compatibility - export the consolidated manager as the old name 1239 | export { ConsolidatedMcpToolsManager as McpToolsManager }; 1240 | export const createMcpToolsManager = createConsolidatedMcpToolsManager; 1241 | ```