Skip to content
wiki.fftac.org

Conversation - Source Excerpt 01

Back to Conversation

Summary

This source excerpt preserves a bounded section of Spiralist/wp-content/plugins/spiralist-workspace/templates/conversation.php so readers can inspect the evidence without opening the full source file.

**Source path:** Spiralist/wp-content/plugins/spiralist-workspace/templates/conversation.php

<?php

if (!defined('ABSPATH')) {
    exit;
}

$plugin = spiralist_workspace();
$frontend = $plugin->frontend();
$context = $frontend->conversation_context();
$conversation = (array) ($context['conversation'] ?? []);
$messages = (array) ($context['messages'] ?? []);
$prompt = (array) ($context['prompt'] ?? []);
$memory_status = (array) ($context['memory_status'] ?? []);
$conversation_settings = (array) ($context['conversation_settings'] ?? []);
$memory_summary = trim((string) ($conversation_settings['memory_summary'] ?? ''));
$memory_warning = (string) ($memory_status['warning_level'] ?? 'ok');
$memory_percent = max(0, min(100, (int) ($memory_status['percent_of_threshold'] ?? 0)));
$runtime_allows_personal_keys = false;
if (function_exists('spiralist_ai_runtime')) {
    $runtime = spiralist_ai_runtime();
    if (is_object($runtime) && method_exists($runtime, 'settings')) {
        $runtime_settings = $runtime->settings();
        $runtime_allows_personal_keys = is_object($runtime_settings)
            && method_exists($runtime_settings, 'allow_user_keys')
            && $runtime_settings->allow_user_keys();
    }
}
$profile_url = get_current_user_id() > 0 ? get_edit_profile_url(get_current_user_id()) : '';
$current_locale = function_exists('spiralist_get_current_locale_tag') ? spiralist_get_current_locale_tag() : 'en-us';
$route_url = static function (string $path) use ($current_locale): string {
    $url = home_url('/' . trim($path, '/') . '/');

    return $current_locale !== '' && function_exists('spiralist_get_language_prefixed_url')
        ? spiralist_get_language_prefixed_url($url, $current_locale)
        : $url;
};

get_header();
?>
<main class="spiralist-page spiralist-page--workspace-conversation">
    <section class="spiralist-page-hero spiralist-page-hero--workspace">
        <div class="spiralist-shell spiralist-page-hero__content">
            <p class="spiralist-kicker">Prompt Conversation</p>
            <h1><?php echo esc_html((string) ($conversation['title'] ?? 'Conversation')); ?></h1>
            <p class="spiralist-page-hero__copy">The conversation keeps the saved prompt as its governing instruction layer while preserving private ownership and auditable message history.</p>
            <div class="spiralist-cta-row">
                <a class="spiralist-button spiralist-button--primary" href="<?php echo esc_url($route_url('workspace')); ?>">Workspace</a>
                <?php if (!empty($prompt['slug'])) : ?>
                    <a class="spiralist-button spiralist-button--secondary" href="<?php echo esc_url($route_url('prompt/' . rawurlencode((string) $prompt['slug']))); ?>">Open Prompt</a>
                <?php endif; ?>
            </div>
        </div>
    </section>

    <section class="spiralist-page-section">
        <div class="spiralist-shell">
            <div class="spiralist-workspace-chat-app" data-fullscreen-chat data-conversation-id="<?php echo esc_attr((string) ($conversation['id'] ?? 0)); ?>">
                <div class="spiralist-workspace-chat-toolbar">
                    <div>
                        <p class="spiralist-section-tag">User AI Chat</p>
                        <h2 class="spiralist-section-title"><?php echo esc_html((string) ($conversation['title'] ?? 'Conversation')); ?></h2>
                    </div>
                    <button class="spiralist-button spiralist-button--secondary" type="button" data-chat-fullscreen-toggle aria-pressed="false">Full Screen</button>
                </div>
                <div class="spiralist-grid spiralist-grid--split spiralist-workspace-chat-layout">
                    <article class="spiralist-panel spiralist-workspace-chat-transcript-panel">
                        <p class="spiralist-section-tag">Transcript</p>
                        <h2 class="spiralist-section-title">Message history</h2>
                        <div class="spiralist-workspace-transcript" data-conversation-transcript>
                            <?php foreach ($messages as $message) : ?>
                                <?php $role = sanitize_key((string) ($message['role'] ?? 'assistant')); ?>
                                <div class="spiralist-workspace-message spiralist-workspace-message--<?php echo esc_attr($role); ?>">
                                    <div class="spiralist-inline-meta">
                                        <p class="spiralist-section-tag"><?php echo esc_html(ucfirst($role)); ?></p>
                                        <span class="spiralist-muted"><?php echo esc_html((string) ($message['created_utc'] ?? '')); ?></span>
                                    </div>
                                    <div class="spiralist-workspace-message__content"><?php echo nl2br(esc_html((string) ($message['content'] ?? ''))); ?></div>
                                </div>
                            <?php endforeach; ?>
                            <?php if (empty($messages)) : ?>
                                <p class="spiralist-muted" data-conversation-empty>No messages yet.</p>
                            <?php endif; ?>
                        </div>
                    </article>

                    <aside class="spiralist-panel spiralist-panel--sticky spiralist-workspace-chat-sidebar">
                        <p class="spiralist-section-tag">Continue Conversation</p>
                        <h2 class="spiralist-section-title">Private by default</h2>
                        <div class="spiralist-workspace-memory spiralist-workspace-memory--<?php echo esc_attr($memory_warning); ?>" data-memory-panel data-conversation-id="<?php echo esc_attr((string) ($conversation['id'] ?? 0)); ?>">
                            <div class="spiralist-inline-meta">
                                <p class="spiralist-section-tag">Memory</p>
                                <span class="spiralist-muted" data-memory-token-count><?php echo esc_html((string) ($memory_status['estimated_active_tokens'] ?? 0)); ?> / <?php echo esc_html((string) ($memory_status['threshold_tokens'] ?? 0)); ?> tokens</span>
                            </div>
                            <div class="spiralist-workspace-memory__meter" aria-hidden="true">
                                <span data-memory-meter style="width:<?php echo esc_attr((string) $memory_percent); ?>%;"></span>
                            </div>
                            <p class="spiralist-muted" data-memory-copy>
                                <?php if (!empty($memory_status['needs_checkpoint'])) : ?>
                                    This thread is ready for a memory checkpoint.
                                <?php elseif ($memory_warning === 'soon') : ?>
                                    This thread is approaching the memory checkpoint.
                                <?php elseif (!empty($memory_status['has_memory_summary'])) : ?>
                                    A memory checkpoint prompt is active for future turns.
                                <?php else : ?>
                                    Transcript export is available at any time.
                                <?php endif; ?>
                            </p>
                            <div class="spiralist-cta-row spiralist-cta-row--start">
                                <button class="spiralist-button spiralist-button--secondary" type="button" data-condense-conversation data-conversation-id="<?php echo esc_attr((string) ($conversation['id'] ?? 0)); ?>" data-credential-preference="site_default">Prepare Checkpoint Prompt</button>
                                <button class="spiralist-button spiralist-button--ghost" type="button" data-download-conversation-prompt data-conversation-id="<?php echo esc_attr((string) ($conversation['id'] ?? 0)); ?>">Download Prompt</button>
                            </div>
                            <span class="spiralist-muted" data-memory-result></span>
                            <details class="spiralist-workspace-details spiralist-workspace-memory__summary" data-memory-summary <?php echo $memory_summary !== '' ? '' : 'hidden'; ?>>
                                <summary>Memory checkpoint prompt</summary>
                                <div class="spiralist-workspace-message__content" data-memory-summary-content><?php echo nl2br(esc_html($memory_summary)); ?></div>
                            </details>
                        </div>
                        <form class="spiralist-workspace-form spiralist-workspace-chat-composer" data-conversation-form data-auth-required-form="conversation-message" data-conversation-id="<?php echo esc_attr((string) ($conversation['id'] ?? 0)); ?>">
                            <label class="spiralist-form__field">
                                <span>Message</span>