do-memory-mcp 0.1.26

Model Context Protocol (MCP) server with secure code execution sandbox for AI agents
Documentation
//! Comprehensive database integration test for Memory MCP
//!
//! This test demonstrates full database functionality by running
//! memory operations and MCP queries in the same process.

use do_memory_core::{
    ComplexityLevel, ExecutionStep, MemoryConfig, SelfLearningMemory, TaskContext, TaskOutcome,
    TaskType,
};
use do_memory_mcp::{ExecutionContext, MemoryMCPServer, SandboxConfig};
use serde_json::json;
use std::sync::Arc;

#[tokio::test]
async fn test_comprehensive_database_operations() {
    println!("๐Ÿงช Starting Comprehensive Database Operations Test");

    // Initialize memory system
    let memory = Arc::new(SelfLearningMemory::with_config(MemoryConfig {
        quality_threshold: 0.0,
        batch_config: None, // Disable batching for tests for test episodes
        ..Default::default()
    }));
    let sandbox_config = SandboxConfig::restrictive();
    let mcp_server = Arc::new(
        MemoryMCPServer::new(sandbox_config, memory.clone())
            .await
            .unwrap(),
    );

    println!("โœ… Memory system and MCP server initialized");

    // Test 1: Episode Creation and Storage
    println!("\n๐Ÿ“ Test 1: Episode Creation and Storage");

    let episode_id = memory
        .start_episode(
            "Build Web Todo List with Local Storage".to_string(),
            TaskContext {
                domain: "web".to_string(),
                language: Some("javascript".to_string()),
                framework: Some("vanilla-js".to_string()),
                complexity: ComplexityLevel::Moderate,
                tags: vec![
                    "web".to_string(),
                    "todo".to_string(),
                    "local-storage".to_string(),
                ],
            },
            TaskType::CodeGeneration,
        )
        .await;

    println!("โœ… Episode created successfully");

    // Log execution steps
    let steps = vec![
        ExecutionStep::new(
            1,
            "create_html".to_string(),
            "Create Web HTML structure".to_string(),
        ),
        ExecutionStep::new(
            2,
            "add_manifest".to_string(),
            "Add Web App Manifest".to_string(),
        ),
        ExecutionStep::new(
            3,
            "implement_service_worker".to_string(),
            "Implement service worker for offline support".to_string(),
        ),
        ExecutionStep::new(
            4,
            "add_local_storage".to_string(),
            "Implement localStorage for data persistence".to_string(),
        ),
    ];

    for (i, mut step) in steps.into_iter().enumerate() {
        step.parameters = json!({
            "step": i + 1,
            "description": format!("Step {} implementation", i + 1)
        });
        step.result = Some(do_memory_core::ExecutionResult::Success {
            output: format!("Step {} completed successfully", i + 1),
        });
        step.latency_ms = (i as u64 + 1) * 100;
        step.tokens_used = Some((i + 1) * 50);

        memory.log_step(episode_id, step).await;
    }

    println!("โœ… {} execution steps logged", 4);

    // Complete the episode
    let outcome = TaskOutcome::Success {
        verdict: "Web Todo List implemented successfully with local storage and offline support"
            .to_string(),
        artifacts: vec![
            "index.html".to_string(),
            "manifest.json".to_string(),
            "sw.js".to_string(),
        ],
    };

    memory.complete_episode(episode_id, outcome).await.unwrap();
    println!("โœ… Episode completed successfully");

    // Test 2: MCP Memory Query
    println!("\n๐Ÿ” Test 2: MCP Memory Query");

    let query_result = mcp_server
        .query_memory(
            "Web todo list".to_string(),
            "web".to_string(),
            None,
            10,
            "relevance".to_string(),
            None,
        )
        .await
        .unwrap();

    let episodes = query_result["episodes"].as_array().unwrap();
    assert_eq!(episodes.len(), 1, "Should find exactly 1 episode");

    let episode = &episodes[0];
    assert_eq!(
        episode["task_description"],
        "Build Web Todo List with Local Storage"
    );
    assert_eq!(episode["steps"].as_array().unwrap().len(), 4);

    let insights = &query_result["insights"];
    assert_eq!(insights["total_episodes"], 1);
    assert!(insights["success_rate"].as_f64().unwrap() > 0.0);

    println!(
        "โœ… Memory query returned {} episodes with {} patterns",
        episodes.len(),
        query_result["patterns"].as_array().unwrap().len()
    );

    // Test 3: Pattern Analysis
    println!("\n๐Ÿ“Š Test 3: Pattern Analysis");

    let pattern_result = mcp_server
        .analyze_patterns(
            "CodeGeneration".to_string(),
            0.0, // Include all patterns
            10,
            None,
        )
        .await
        .unwrap();

    let patterns = pattern_result["patterns"].as_array().unwrap();
    let statistics = &pattern_result["statistics"];

    println!("โœ… Pattern analysis found {} patterns", patterns.len());
    println!(
        "   ๐Ÿ“ˆ Statistics: {} total, avg success rate: {:.2}",
        statistics["total_patterns"], statistics["avg_success_rate"]
    );

    // Test 4: Tool Usage Tracking
    println!("\n๐Ÿ“ˆ Test 4: Tool Usage Tracking");

    // Perform additional tool operations
    let _ = mcp_server
        .query_memory(
            "test".to_string(),
            "test".to_string(),
            None,
            1,
            "relevance".to_string(),
            None,
        )
        .await
        .unwrap();
    let _ = mcp_server
        .analyze_patterns("test".to_string(), 0.5, 5, None)
        .await
        .unwrap();

    let usage = mcp_server.get_tool_usage().await;
    assert!(usage.contains_key("query_memory"));
    assert!(usage.contains_key("analyze_patterns"));
    assert!(*usage.get("query_memory").unwrap_or(&0) >= 2); // At least 2 calls
    assert!(*usage.get("analyze_patterns").unwrap_or(&0) >= 2); // At least 2 calls

    println!(
        "โœ… Tool usage tracking verified: {} tools tracked",
        usage.len()
    );

    // Test 5: Code Execution and Statistics
    println!("\nโšก Test 5: Code Execution and Statistics");

    // Test safe code execution
    let code = r#"
        const todoApp = {
            addTodo: (text) => ({ id: Date.now(), text, completed: false }),
            toggleTodo: (todo) => ({ ...todo, completed: !todo.completed }),
            getStats: (todos) => ({
                total: todos.length,
                completed: todos.filter(t => t.completed).length,
                active: todos.filter(t => !t.completed).length
            })
        };

        const todos = [
            todoApp.addTodo("Learn Web"),
            todoApp.addTodo("Build todo app"),
            todoApp.toggleTodo(todoApp.addTodo("Test offline"))
        ];

        return {
            todos,
            stats: todoApp.getStats(todos),
            message: "Web Todo functionality working!"
        };
    "#;

    let context = ExecutionContext::new(
        "Test Web todo logic".to_string(),
        json!({"test": "web-functionality"}),
    );

    let _exec_result = mcp_server
        .execute_agent_code(code.to_string(), context)
        .await;

    // Check execution statistics regardless of success/failure
    let stats = mcp_server.get_stats().await;
    assert!(stats.total_executions >= 1);
    println!(
        "โœ… Execution statistics: {} total, {} successful, {} failed",
        stats.total_executions, stats.successful_executions, stats.failed_executions
    );

    // Test 6: Data Persistence Verification
    println!("\n๐Ÿ’พ Test 6: Data Persistence Verification");

    // Query the same episode again to verify persistence
    let verify_result = mcp_server
        .query_memory(
            "Web todo list".to_string(),
            "web".to_string(),
            None,
            10,
            "relevance".to_string(),
            None,
        )
        .await
        .unwrap();

    let verify_episodes = verify_result["episodes"].as_array().unwrap();
    assert_eq!(verify_episodes.len(), 1, "Episode should persist in memory");

    let verify_episode = &verify_episodes[0];
    assert_eq!(
        verify_episode["task_description"],
        "Build Web Todo List with Local Storage"
    );
    assert_eq!(verify_episode["steps"].as_array().unwrap().len(), 4);

    println!("โœ… Data persistence verified - episode and steps maintained");

    // Test 7: Comprehensive Statistics
    println!("\n๐Ÿ“Š Test 7: Comprehensive Statistics");

    let final_usage = mcp_server.get_tool_usage().await;
    let final_stats = mcp_server.get_stats().await;

    println!("๐Ÿ“ˆ Final Tool Usage:");
    for (tool, count) in final_usage.iter() {
        println!("   - {}: {} calls", tool, count);
    }

    println!("๐Ÿ“Š Final Execution Statistics:");
    println!("   - Total executions: {}", final_stats.total_executions);
    println!("   - Successful: {}", final_stats.successful_executions);
    println!("   - Failed: {}", final_stats.failed_executions);
    println!(
        "   - Security violations: {}",
        final_stats.security_violations
    );

    // Test 8: Memory Pattern Retrieval
    println!("\n๐Ÿง  Test 8: Memory Pattern Retrieval");

    let patterns_result = memory
        .retrieve_relevant_patterns(
            &TaskContext {
                domain: "web".to_string(),
                language: Some("javascript".to_string()),
                framework: Some("vanilla-js".to_string()),
                complexity: ComplexityLevel::Moderate,
                tags: vec!["web".to_string()],
            },
            10,
        )
        .await;

    println!(
        "โœ… Pattern retrieval completed - found {} patterns",
        patterns_result.len()
    );

    println!("\n๐ŸŽ‰ Comprehensive Database Operations Test Completed Successfully!");
    println!("โœ… All database operations verified:");
    println!("   - Episode creation and storage");
    println!("   - Step logging and retrieval");
    println!("   - Episode completion and analysis");
    println!("   - MCP memory queries");
    println!("   - Pattern extraction and analysis");
    println!("   - Tool usage tracking");
    println!("   - Code execution statistics");
    println!("   - Data persistence verification");
}