Skip to content
wiki.fftac.org

AI Engine - Source Excerpt 05

Back to AI Engine

Summary

This source excerpt preserves a bounded section of Anti-Christ.org/wp-content/plugins/fftac-ai-engine/inc/ai-engine.php so readers can inspect the evidence without opening the full source file.

**Source path:** Anti-Christ.org/wp-content/plugins/fftac-ai-engine/inc/ai-engine.php

return 1 === preg_match('/^sk-[A-Za-z0-9_\-]{16,240}$/', $api_key);
}

/**
 * Normalizes a submitted API key without logging or displaying it.
 *
 * @param string $api_key Raw API key.
 * @return string
 */
function antichrist_engine_foundation_ai_normalize_user_api_key($api_key)
{
    return preg_replace('/\s+/', '', trim((string) $api_key));
}

/**
 * Saves a user's encrypted OpenAI API key.
 *
 * @param int    $user_id User ID.
 * @param string $api_key API key.
 * @return bool
 */
function antichrist_engine_foundation_ai_save_user_api_key($user_id, $api_key)
{
    $user_id = absint($user_id);
    $api_key = antichrist_engine_foundation_ai_normalize_user_api_key($api_key);

    if (!$user_id || !antichrist_engine_foundation_ai_is_valid_user_api_key($api_key)) {
        return false;
    }

    $encrypted = antichrist_engine_foundation_ai_encrypt_secret($api_key);

    if (!$encrypted) {
        return false;
    }

    $meta_keys = antichrist_engine_foundation_ai_get_user_key_meta_keys();

    update_user_meta($user_id, $meta_keys['encrypted'], $encrypted);
    update_user_meta($user_id, $meta_keys['hint'], substr($api_key, -4));
    update_user_meta($user_id, $meta_keys['saved_at'], gmdate('c'));

    return true;
}

/**
 * Deletes a user's stored OpenAI API key.
 *
 * @param int $user_id User ID.
 * @return void
 */
function antichrist_engine_foundation_ai_delete_user_api_key($user_id)
{
    $user_id = absint($user_id);

    if (!$user_id) {
        return;
    }

    foreach (antichrist_engine_foundation_ai_get_user_key_meta_keys() as $meta_key) {
        delete_user_meta($user_id, $meta_key);
    }
}

/**
 * Gets a decrypted user API key.
 *
 * @param int $user_id User ID.
 * @return string
 */
function antichrist_engine_foundation_ai_get_user_api_key($user_id)
{
    $user_id = absint($user_id);

    if (!$user_id) {
        return '';
    }

    $meta_keys = antichrist_engine_foundation_ai_get_user_key_meta_keys();
    $stored = (string) get_user_meta($user_id, $meta_keys['encrypted'], true);

    return antichrist_engine_foundation_ai_decrypt_secret($stored);
}

/**
 * Gets safe user key status for display.
 *
 * @param int $user_id User ID.
 * @return array<string, mixed>
 */
function antichrist_engine_foundation_ai_get_user_key_status($user_id)
{
    $user_id = absint($user_id);
    $meta_keys = antichrist_engine_foundation_ai_get_user_key_meta_keys();
    $api_key = $user_id ? antichrist_engine_foundation_ai_get_user_api_key($user_id) : '';

    return array(
        'has_key'  => '' !== $api_key,
        'hint'     => $user_id ? (string) get_user_meta($user_id, $meta_keys['hint'], true) : '',
        'saved_at' => $user_id ? (string) get_user_meta($user_id, $meta_keys['saved_at'], true) : '',
    );
}

/**
 * Sanitizes AI plain text without stripping code-like angle brackets.
 *
 * @param mixed $value Raw text.
 * @param int   $max_length Maximum text length.
 * @return string
 */
function antichrist_engine_foundation_ai_sanitize_plain_text($value, $max_length)
{
    $value = is_scalar($value) ? (string) $value : '';
    $value = str_replace(array("\r\n", "\r"), "\n", $value);
    $value = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/', '', $value);

    return trim(antichrist_engine_security_limit_string((string) $value, $max_length));
}

/**
 * Sanitizes a browser-submitted AI conversation history.
 *
 * @param mixed $raw_history Raw JSON string or array.
 * @param int   $max_messages Maximum message count.
 * @param int   $max_message_length Maximum length per message.
 * @return array<int, array<string, string>>
 */
function antichrist_engine_foundation_ai_sanitize_history($raw_history, $max_messages = 10, $max_message_length = 1400)
{
    if (is_scalar($raw_history)) {
        $decoded = json_decode((string) $raw_history, true);
    } elseif (is_array($raw_history)) {
        $decoded = $raw_history;
    } else {
        $decoded = array();
    }

    if (!is_array($decoded)) {
        return array();
    }

    $history = array();

    foreach ($decoded as $message) {
        if (!is_array($message)) {
            continue;
        }

        $role = sanitize_key((string) ($message['role'] ?? ''));

        if (!in_array($role, array('user', 'assistant'), true)) {
            continue;
        }

        $content = antichrist_engine_foundation_ai_sanitize_plain_text((string) ($message['content'] ?? ''), $max_message_length);

        if (!$content) {
            continue;
        }

        $history[] = array(
            'role'    => $role,
            'content' => $content,
        );
    }

    return array_slice($history, -absint($max_messages));
}

/**
 * Counts sanitized conversation characters.
 *
 * @param array<int, array<string, string>> $history Conversation history.
 * @return int
 */
function antichrist_engine_foundation_ai_get_history_character_count($history)
{
    $count = 0;

    foreach ((array) $history as $message) {
        $count += strlen((string) ($message['content'] ?? ''));
    }

    return $count;
}

/**
 * Selects the API key and quota policy for a request.
 *
 * @param string                             $prompt Prompt.
 * @param array<int, array<string, string>> $history Conversation history.
 * @param int                                $user_id User ID.
 * @return array<string, mixed>
 */
function antichrist_engine_foundation_ai_select_api_key_for_request($prompt, $history = array(), $user_id = 0)
{
    $prompt = (string) $prompt;
    $history = is_array($history) ? $history : array();
    $prompt_length = strlen($prompt);
    $context_length = $prompt_length + antichrist_engine_foundation_ai_get_history_character_count($history);
    $user_key = $user_id ? antichrist_engine_foundation_ai_get_user_api_key($user_id) : '';

    if ($user_key) {
        $prompt_limit = antichrist_engine_foundation_ai_get_user_key_prompt_limit();
        $context_limit = antichrist_engine_foundation_ai_get_user_key_context_limit();

        if ($prompt_length > $prompt_limit || $context_length > $context_limit) {
            return array(
                'status'        => 'too_long',
                'code'          => 'too_long',
                'message'       => sprintf('Keep personal-key prompts under %1$s characters and the local conversation context under %2$s characters.', number_format_i18n($prompt_limit), number_format_i18n($context_limit)),
                'key_required'  => false,
                'prompt_limit'  => $prompt_limit,
                'context_limit' => $context_limit,
            );
        }

        return array(
            'status'            => 'ok',
            'api_key'           => $user_key,
            'source'            => 'user',
            'prompt_limit'      => $prompt_limit,
            'context_limit'     => $context_limit,
            'rate_limit'        => 20,
            'rate_window'       => HOUR_IN_SECONDS,
            'max_output_tokens' => antichrist_engine_foundation_ai_get_max_output_tokens('user'),
        );
    }

    $site_key = antichrist_engine_foundation_ai_get_api_key();

    if ($site_key) {
        $prompt_limit = antichrist_engine_foundation_ai_get_site_key_prompt_limit();
        $context_limit = antichrist_engine_foundation_ai_get_site_key_context_limit();

        if ($prompt_length > $prompt_limit || $context_length > $context_limit) {
            return array(
                'status'        => 'needs_user_key',
                'code'          => 'user_key_required',
                'message'       => sprintf('This request is larger than the limited Foundation key allows. Save your own OpenAI API key for prompts over %1$s characters or conversation context over %2$s characters.', number_format_i18n($prompt_limit), number_format_i18n($context_limit)),
                'key_required'  => true,
                'prompt_limit'  => $prompt_limit,
                'context_limit' => $context_limit,
            );
        }

        return array(
            'status'            => 'ok',
            'api_key'           => $site_key,
            'source'            => 'site',
            'prompt_limit'      => $prompt_limit,
            'context_limit'     => $context_limit,
            'rate_limit'        => 3,
            'rate_window'       => HOUR_IN_SECONDS,
            'max_output_tokens' => antichrist_engine_foundation_ai_get_max_output_tokens('site'),
        );
    }

    return array(
        'status'       => 'needs_user_key',
        'code'         => 'user_key_required',
        'message'      => 'Live AI responses need a saved personal OpenAI API key until a limited Foundation key is configured.',
        'key_required' => true,
    );
}

/**