contaigents
Version:
Modular AI Content Ecosystem with Audio Generation
192 lines (191 loc) โข 10.8 kB
JavaScript
/**
* Phase 2 Test: State Storage & Detection
*
* This test verifies that:
* 1. StateManager can create story projects with initial state
* 2. StateManager can read and parse YAML frontmatter
* 3. StateManager can update workflow state
* 4. StateManager can update user preferences
* 5. ChatService detects story projects and loads state
* 6. ChatService appends state context to system prompt
*/
import { StateManager } from '../services/stateManager.js';
import { ChatService } from '../services/chatService.js';
import fs from 'fs/promises';
import path from 'path';
async function testPhase2() {
console.log('๐งช Phase 2 Test: State Storage & Detection\n');
const testDir = path.join(process.cwd(), 'test_phase2_output');
try {
// Create test directory
await fs.mkdir(testDir, { recursive: true });
console.log(`โ Created test directory: ${testDir}\n`);
// Test 1: StateManager - Create Story Project
console.log('Test 1: Create Story Project');
console.log('='.repeat(60));
const stateManager = new StateManager(testDir);
await stateManager.createStoryProject('Test Detective Story', 'A detective investigates a mysterious case in a futuristic city.');
const hasProject = await stateManager.hasStoryProject();
console.log(` โ Story project created: ${hasProject ? 'โ
' : 'โ'}`);
// Test 2: StateManager - Read State
console.log('\nTest 2: Read State');
console.log('='.repeat(60));
const parsed = await stateManager.readState();
console.log(` โ State read successfully: ${parsed ? 'โ
' : 'โ'}`);
if (parsed) {
console.log(` โ Workflow state: ${parsed.state.workflow_state}`);
console.log(` โ Auto-generate sketches: ${parsed.state.auto_generate_sketches}`);
console.log(` โ Sketch style: ${parsed.state.sketch_style_preference}`);
console.log(` โ Created at: ${parsed.state.created_at}`);
console.log(` โ Last updated: ${parsed.state.last_updated}`);
console.log(` โ Content length: ${parsed.content.length} chars`);
}
// Test 3: StateManager - Update Workflow State
console.log('\nTest 3: Update Workflow State');
console.log('='.repeat(60));
await stateManager.updateWorkflowState('OUTLINE_CONFIRMED');
const updatedState = await stateManager.getCurrentState();
console.log(` โ State updated to: ${updatedState}`);
console.log(` โ State is OUTLINE_CONFIRMED: ${updatedState === 'OUTLINE_CONFIRMED' ? 'โ
' : 'โ'}`);
// Test 4: StateManager - Update Preferences
console.log('\nTest 4: Update Preferences');
console.log('='.repeat(60));
await stateManager.updatePreferences({
auto_generate_sketches: true,
sketch_style_preference: 'cinematic'
});
const autoSketch = await stateManager.isAutoSketchEnabled();
const sketchStyle = await stateManager.getSketchStyle();
console.log(` โ Auto-sketch enabled: ${autoSketch ? 'โ
' : 'โ'}`);
console.log(` โ Sketch style: ${sketchStyle}`);
console.log(` โ Sketch style is cinematic: ${sketchStyle === 'cinematic' ? 'โ
' : 'โ'}`);
// Test 5: StateManager - State Constraints
console.log('\nTest 5: State Constraints');
console.log('='.repeat(60));
const states = ['OUTLINE_DRAFT', 'OUTLINE_CONFIRMED', 'SCREENPLAY_WRITING', 'ITERATION'];
for (const state of states) {
const constraints = stateManager.getStateConstraints(state);
console.log(` โ ${state}:`);
console.log(` - Can generate screenplay: ${constraints.canGenerateScreenplay}`);
console.log(` - Can generate sketches: ${constraints.canGenerateSketches}`);
console.log(` - Can edit outline: ${constraints.canEditOutline}`);
console.log(` - Can iterate: ${constraints.canIterate}`);
}
// Test 6: StateManager - State Transitions
console.log('\nTest 6: State Transitions');
console.log('='.repeat(60));
const validTransitions = [
{ from: 'OUTLINE_DRAFT', to: 'OUTLINE_CONFIRMED', expected: true },
{ from: 'OUTLINE_DRAFT', to: 'SCREENPLAY_WRITING', expected: false },
{ from: 'OUTLINE_CONFIRMED', to: 'SCREENPLAY_WRITING', expected: true },
{ from: 'SCREENPLAY_WRITING', to: 'ITERATION', expected: true },
{ from: 'ITERATION', to: 'OUTLINE_DRAFT', expected: true }
];
for (const transition of validTransitions) {
const isValid = stateManager.validateStateTransition(transition.from, transition.to);
const result = isValid === transition.expected ? 'โ
' : 'โ';
console.log(` ${result} ${transition.from} โ ${transition.to}: ${isValid ? 'valid' : 'invalid'}`);
}
// Test 7: ChatService - Detect Story Project
console.log('\nTest 7: ChatService - Detect Story Project');
console.log('='.repeat(60));
const chatService = new ChatService(testDir);
const session = await chatService.createSession();
console.log(` โ Session created: ${session.id}`);
console.log(` โ Has story project: ${session.hasStoryProject ? 'โ
' : 'โ'}`);
console.log(` โ Story project state: ${session.storyProjectState?.workflow_state || 'none'}`);
// Test 8: ChatService - State Context in System Prompt
console.log('\nTest 8: State Context in System Prompt');
console.log('='.repeat(60));
const systemMessage = session.messages.find(m => m.role === 'system');
if (systemMessage) {
const hasStateContext = systemMessage.content.includes('Current Story Project Context');
const hasWorkflowState = systemMessage.content.includes('Current Workflow State');
const hasAutoSketch = systemMessage.content.includes('Auto-generate Sketches');
console.log(` โ System message exists: โ
`);
console.log(` โ Has state context: ${hasStateContext ? 'โ
' : 'โ'}`);
console.log(` โ Has workflow state: ${hasWorkflowState ? 'โ
' : 'โ'}`);
console.log(` โ Has auto-sketch info: ${hasAutoSketch ? 'โ
' : 'โ'}`);
if (hasStateContext) {
console.log('\n ๐ State Context Snippet:');
const contextStart = systemMessage.content.indexOf('Current Story Project Context');
const contextSnippet = systemMessage.content.substring(contextStart, contextStart + 300);
console.log(` ${contextSnippet}...`);
}
}
// Test 9: ChatService - Refresh State
console.log('\nTest 9: ChatService - Refresh State');
console.log('='.repeat(60));
// Update state directly
await stateManager.updateWorkflowState('SCREENPLAY_WRITING');
// Refresh state in session
await chatService.refreshStoryProjectState(session.id);
const refreshedSession = chatService.getSession(session.id);
console.log(` โ State refreshed: ${refreshedSession?.storyProjectState?.workflow_state === 'SCREENPLAY_WRITING' ? 'โ
' : 'โ'}`);
console.log(` โ New state: ${refreshedSession?.storyProjectState?.workflow_state}`);
// Test 10: ChatService - No Story Project
console.log('\nTest 10: ChatService - No Story Project');
console.log('='.repeat(60));
const emptyDir = path.join(testDir, 'empty');
await fs.mkdir(emptyDir, { recursive: true });
const chatServiceEmpty = new ChatService(emptyDir);
const emptySession = await chatServiceEmpty.createSession();
console.log(` โ Session created: ${emptySession.id}`);
console.log(` โ Has story project: ${emptySession.hasStoryProject ? 'โ' : 'โ
'}`);
console.log(` โ Story project state: ${emptySession.storyProjectState ? 'โ' : 'โ
(none)'}`);
const emptySystemMessage = emptySession.messages.find(m => m.role === 'system');
if (emptySystemMessage) {
const hasStateContext = emptySystemMessage.content.includes('Current Story Project Context');
console.log(` โ No state context in system prompt: ${!hasStateContext ? 'โ
' : 'โ'}`);
}
// Summary
console.log('\n' + '='.repeat(60));
console.log('๐ Phase 2 Test Summary');
console.log('='.repeat(60));
const allTests = [
hasProject,
parsed !== null,
updatedState === 'OUTLINE_CONFIRMED',
autoSketch === true,
sketchStyle === 'cinematic',
session.hasStoryProject === true,
session.storyProjectState?.workflow_state === 'OUTLINE_CONFIRMED',
systemMessage?.content.includes('Current Story Project Context') === true,
refreshedSession?.storyProjectState?.workflow_state === 'SCREENPLAY_WRITING',
emptySession.hasStoryProject === false
];
const passedTests = allTests.filter(t => t).length;
const totalTests = allTests.length;
const passRate = ((passedTests / totalTests) * 100).toFixed(1);
console.log(`\nTests Passed: ${passedTests}/${totalTests} (${passRate}%)`);
if (passedTests === totalTests) {
console.log('\nโ
All Phase 2 tests passed! State management is working correctly:');
console.log(' - Story projects can be created with initial state');
console.log(' - State can be read and parsed from YAML frontmatter');
console.log(' - Workflow state can be updated');
console.log(' - User preferences can be updated');
console.log(' - ChatService detects story projects');
console.log(' - ChatService loads state into sessions');
console.log(' - State context is appended to system prompts');
console.log(' - State can be refreshed during conversations');
}
else {
console.log('\nโ ๏ธ Some tests failed. Review the output above.');
}
// Cleanup
console.log(`\n๐งน Cleaning up test directory: ${testDir}`);
await fs.rm(testDir, { recursive: true, force: true });
console.log('โ Cleanup complete\n');
}
catch (error) {
console.error('โ Test failed with error:', error);
// Cleanup on error
try {
await fs.rm(testDir, { recursive: true, force: true });
}
catch { }
throw error;
}
}
// Run the test
testPhase2().catch(console.error);