Current File : /home/kelaby89/cartel.express/wp-content/plugins/ai-engine/classes/services/response-id-manager.php
<?php

/**
* Centralized manager for AI response IDs.
*
* Handles storage, retrieval, and validation of response IDs
* used for stateful conversations with various AI APIs.
*/
class Meow_MWAI_Services_ResponseIdManager {
  private Meow_MWAI_Core $core;
  private array $cache = [];

  // Response ID patterns for different providers
  public const OPENAI_RESPONSES_PATTERN = '/^resp_/';
  public const OPENAI_CHAT_PATTERN = '/^chatcmpl-/';
  public const ANTHROPIC_PATTERN = '/^msg_/';

  // Expiry time (30 days as per OpenAI's policy)
  public const EXPIRY_DAYS = 30;

  public function __construct( Meow_MWAI_Core $core ) {
    $this->core = $core;
  }

  /**
  * Store a response ID with metadata
  */
  public function store( string $discussionId, string $responseId, array $metadata = [] ): void {
    $data = [
      'responseId' => $responseId,
      'responseDate' => gmdate( 'Y-m-d H:i:s' ),
      'provider' => $this->detect_provider( $responseId ),
      'apiType' => $this->detect_api_type( $responseId )
    ];

    // Merge additional metadata
    $data = array_merge( $data, $metadata );

    // Cache for current request
    $this->cache[$discussionId] = $data;

    // Let the discussion system handle persistence
    // This is called by the chatbot module when storing discussions
  }

  /**
  * Retrieve a response ID if valid
  */
  public function retrieve( string $discussionId, array $extra = [] ): ?string {
    // Check cache first
    if ( isset( $this->cache[$discussionId] ) ) {
      $data = $this->cache[$discussionId];
      return $this->is_valid_data( $data ) ? $data['responseId'] : null;
    }

    // Check provided extra data (from discussion storage)
    if ( !empty( $extra['responseId'] ) ) {
      $responseDate = $extra['responseDate'] ?? null;

      if ( $this->is_valid_date( $responseDate ) ) {
        // Cache for future use in this request
        $this->cache[$discussionId] = $extra;
        return $extra['responseId'];
      }
    }

    return null;
  }

  /**
  * Validate a response ID for a specific API type
  */
  public function validate( string $responseId, string $apiType ): bool {
    switch ( $apiType ) {
      case 'openai_responses':
        return $this->is_responses_api_id( $responseId );

      case 'openai_chat':
        return $this->is_chat_completions_id( $responseId );

      case 'anthropic':
        return $this->is_anthropic_id( $responseId );

      default:
        return true; // Allow unknown types
    }
  }

  /**
  * Check if ID is from OpenAI Responses API
  */
  public function is_responses_api_id( string $responseId ): bool {
    return preg_match( self::OPENAI_RESPONSES_PATTERN, $responseId ) === 1;
  }

  /**
  * Check if ID is from OpenAI Chat Completions API
  */
  public function is_chat_completions_id( string $responseId ): bool {
    return preg_match( self::OPENAI_CHAT_PATTERN, $responseId ) === 1;
  }

  /**
  * Check if ID is from Anthropic
  */
  public function is_anthropic_id( string $responseId ): bool {
    return preg_match( self::ANTHROPIC_PATTERN, $responseId ) === 1;
  }

  /**
  * Check if a response ID is valid for OpenAI Responses API
  * (Alias for is_responses_api_id for backward compatibility)
  */
  public function is_valid_for_responses_api( string $responseId ): bool {
    return $this->is_responses_api_id( $responseId );
  }

  /**
  * Detect provider from response ID format
  */
  private function detect_provider( string $responseId ): string {
    if ( $this->is_responses_api_id( $responseId ) ) {
      return 'openai';
    }
    if ( $this->is_chat_completions_id( $responseId ) ) {
      return 'openai';
    }
    if ( $this->is_anthropic_id( $responseId ) ) {
      return 'anthropic';
    }
    return 'unknown';
  }

  /**
  * Detect API type from response ID format
  */
  private function detect_api_type( string $responseId ): string {
    if ( $this->is_responses_api_id( $responseId ) ) {
      return 'responses_api';
    }
    if ( $this->is_chat_completions_id( $responseId ) ) {
      return 'chat_completions';
    }
    if ( $this->is_anthropic_id( $responseId ) ) {
      return 'messages_api';
    }
    return 'unknown';
  }

  /**
  * Check if stored data is still valid
  */
  private function is_valid_data( array $data ): bool {
    if ( empty( $data['responseId'] ) ) {
      return false;
    }

    $responseDate = $data['responseDate'] ?? null;
    return $this->is_valid_date( $responseDate );
  }

  /**
  * Check if a response date is within validity period
  */
  private function is_valid_date( ?string $responseDate ): bool {
    if ( empty( $responseDate ) ) {
      return false;
    }

    $date = strtotime( $responseDate );
    if ( $date === false ) {
      return false;
    }

    $expiryTime = time() - ( self::EXPIRY_DAYS * 24 * 60 * 60 );
    return $date > $expiryTime;
  }

  /**
  * Clean up expired response IDs (for maintenance)
  */
  public function cleanup_expired(): int {
    // This would be called by a scheduled task
    // Implementation depends on how discussions are stored
    // Return count of cleaned items
    return 0;
  }

  /**
  * Get debug information about a response ID
  */
  public function get_debug_info( string $responseId ): array {
    return [
      'id' => $responseId,
      'provider' => $this->detect_provider( $responseId ),
      'api_type' => $this->detect_api_type( $responseId ),
      'is_valid_responses_api' => $this->is_responses_api_id( $responseId ),
      'is_valid_chat_completions' => $this->is_chat_completions_id( $responseId ),
      'is_valid_anthropic' => $this->is_anthropic_id( $responseId )
    ];
  }
}
Page not found – Hello World !