UNPKG

meld

Version:

Meld: A template language for LLM prompts

209 lines (178 loc) 7.19 kB
## NEW: Transformation Flow Analysis 1. **DirectiveService Implementation Issue**: ```typescript // In DirectiveService.processDirective: const result = await handler.execute(node, context); return result.state; // <-- CRITICAL: Discarding replacement node! ``` - DirectiveService gets replacement nodes from handlers but doesn't use them - Handlers properly generate replacements (verified in RunDirectiveHandler, ImportDirectiveHandler, etc.) - But DirectiveService only returns the state, losing the transformations 2. **Handler Behavior**: - Handlers correctly implement transformation: ```typescript // Example from RunDirectiveHandler: if (clonedState.isTransformationEnabled()) { return { state: clonedState, replacement: { type: 'Text', content: stdout, location: node.location } }; } ``` - All execution handlers follow this pattern - Definition handlers return empty text nodes when transformed 3. **State Management**: - State tracks transformation correctly: - `isTransformationEnabled()` - `setTransformedNodes()` - `transformNode()` - But transformations never make it to OutputService 4. **Expected vs Actual Flow**: - Expected: 1. DirectiveService processes directive 2. Handler returns replacement node 3. DirectiveService updates state's transformed nodes 4. OutputService receives transformed nodes - Actual: 1. DirectiveService processes directive 2. Handler returns replacement node 3. DirectiveService discards replacement 4. OutputService gets original nodes ## NEW: InterpreterService Analysis 1. **Node Processing Flow**: ```typescript // In InterpreterService.interpretNode: case 'Directive': const directiveState = currentState.clone(); directiveState.addNode(node); // Adds original node currentState = await this.directiveService.processDirective(directiveNode, { state: directiveState, currentFilePath: state.getCurrentFilePath() ?? undefined }); ``` - InterpreterService adds original node to state BEFORE processing - Then calls DirectiveService but discards any replacement nodes - This means transformed nodes are never stored in state 2. **State Management**: - Creates clean state for each node interpretation - Properly clones state to maintain immutability - But doesn't handle transformed nodes specially - No awareness of transformation mode 3. **Pipeline Flow**: ``` InterpreterService -> Adds original node to state -> Calls DirectiveService.processDirective -> Handler returns {state, replacement} -> DirectiveService discards replacement -> Returns only state ``` This means: - Original nodes are preserved in state - Transformed nodes are generated but lost - OutputService only sees original nodes ## Root Cause Analysis 1. **Primary Issue**: - DirectiveService discards replacement nodes from handlers - But the problem is more systemic: 1. InterpreterService adds original nodes before transformation 2. DirectiveService discards replacements 3. No service is responsible for managing transformed node list 2. **Required Changes**: a) DirectiveService needs to: - Store replacement nodes in state when transformation enabled - Use `state.transformNode()` to track replacements b) InterpreterService should: - NOT add original nodes for directives in transformation mode - OR add them but mark them for replacement - Let DirectiveService handle node storage in transformation mode 3. **Verification Points**: - Check if StateService's transformed nodes array is ever populated - Verify if any service calls `state.transformNode()` - Look for transformation mode checks in node storage logic ## Next Steps 1. **Fix DirectiveService First**: ```typescript // Current: return result.state; // Should be: if (context.state.isTransformationEnabled?.() && result.replacement) { result.state.transformNode(node, result.replacement); } return result.state; ``` 2. **Then Review InterpreterService**: - Consider moving node addition after directive processing - Add transformation mode awareness - Ensure proper state inheritance of transformed nodes 3. **Finally Check OutputService**: - Verify it properly checks for transformed nodes - Ensure it uses the right node list based on mode 4. **Test Coverage**: - Add tests for transformation state inheritance - Verify node replacement in transformation mode - Test state cloning with transformed nodes ## Mock Implementation Analysis 1. **Multiple Mock Implementations**: - Found two different state mocking approaches: a) `MockStateService` class in `OutputService.test.ts` - full implementation b) `vi.fn()` based mocks in transformation tests - Need to verify consistency between these approaches 2. **Mock State Service Implementation**: ```typescript class MockStateService implements IStateService { private transformationEnabled = false; private transformedNodes: MeldNode[] = []; // Has complete transformation methods: isTransformationEnabled() enableTransformation() setTransformedNodes() getTransformedNodes() transformNode() } ``` - Complete implementation of transformation interface - Proper state tracking for transformed nodes - Correct inheritance in `createChildState()` ## OutputService Investigation 1. **Node Selection Logic**: ```typescript // In OutputService.convert(): const nodesToProcess = state.isTransformationEnabled() && state.getTransformedNodes().length > 0 ? state.getTransformedNodes() : nodes; ``` Questions to investigate: - Is this check for existing transformed nodes intentional? - How should transformed nodes be populated in production? - What's the relationship between manual `setTransformedNodes()` and the transformation pipeline? 2. **Test Setup Pattern**: ```typescript state.enableTransformation(); state.setTransformedNodes(transformedNodes); ``` Need to verify: - Is this manual node setting the intended pattern? - Should we test the full transformation pipeline instead? - How do transformed nodes get populated in real usage? ## Next Steps 1. **Continue Service Audit**: - Review InterpreterService implementation - Understand transformation pipeline flow - Map out how transformed nodes should be populated 2. **Test Infrastructure**: - Consolidate mock implementations - Verify test patterns match intended usage - Consider adding pipeline integration tests 3. **Documentation**: - Map complete transformation lifecycle - Document intended state inheritance patterns - Clarify transformation pipeline responsibilities 4. **Verification Points**: - How transformed nodes get populated in production - Service responsibilities in transformation pipeline - Error handling expectations across pipeline