bedrust 0.8.8

A command line tool to invoke and work with Large Language models on AWS, using Amazon Bedrock
Documentation
<!-- Bedrust Chat Export Template v0.2.0 -->
<!DOCTYPE html>
<html class="bg-gray-50">
<head>
    <title>Bedrust chat export: {{format_title title}}</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.tailwindcss.com"></script>
    <!-- Add Prism.js for syntax highlighting -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism.min.css"/>
    <!-- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/themes/prism-tomorrow.min.css"/> -->
    <style>
        /* Style for code blocks */
        .code-wrapper {
            position: relative;
        }
        
        .copy-button {
            position: absolute;
            right: 8px;
            top: 8px;
            display: none;
            align-items: center;
            padding: 4px 8px;
            font-size: 0.75rem;
            font-weight: 500;
            color: rgb(75 85 99);
            background-color: rgb(243 244 246);
            border-radius: 0.375rem;
            transition: all 200ms;
        }

        .code-wrapper:hover .copy-button {
            display: flex;
        }

        .copy-button:hover {
            background-color: rgb(229 231 235);
        }

        .copy-button svg {
            width: 1rem;
            height: 1rem;
            margin-right: 0.25rem;
        }
        .inline-code {
            background-color: rgb(243 244 246);
            border-radius: 0.25rem;
            font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
            font-size: 0.875em;
            padding: 0.2em 0.4em;
        }
        .source-removed {
            margin: 1rem 0;
            padding: 1rem;
            background: #fafafa;
            border: 1px dashed #d1d5db;
            border-radius: 0.5rem;
            position: relative;
        }

        .source-removed::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            height: 2px;
            background: linear-gradient(to right, #3b82f6, #60a5fa);
            border-radius: 0.5rem 0.5rem 0 0;
        }

        .source-removed-content {
            display: flex;
            align-items: center;
            gap: 0.75rem;
            color: #6b7280;
            font-size: 0.875rem;
            font-weight: 500;
        }

        .source-removed-icon {
            width: 1.25rem;
            height: 1.25rem;
            color: #3b82f6;
            flex-shrink: 0;
        }
        /* Add padding to accommodate the copy button */
        pre[class*="language-"] {
            margin: 1em 0;
            border-radius: 0.375rem;
        }
        
        pre[class*="language-"] code {
            padding-top: 2.5rem !important;
        }
    </style>
</head>
<body class="min-h-screen p-4 md:p-8">
    <div class="max-w-4xl mx-auto bg-white rounded-lg shadow-lg overflow-hidden"> <!-- Added overflow-hidden -->
        <!-- New Top Banner -->
        <div class="bg-slate-900 p-4 flex items-center">
            <div class="flex items-center space-x-2">
                <span class="text-xl font-bold text-white">Bedrust</span>
                <span class="text-2xl">🧠</span>
                <span class="text-2xl">🦀</span>
            </div>
            <!-- Optional: Add a right-side element -->
            <div class="ml-auto text-sm text-gray-400">
                Generated on: {{timestamp}}
            </div>
        </div>
        <!-- New Gradient Title Section -->
        <div class="bg-gradient-to-r from-orange-400 via-pink-500 to-blue-500 p-8 relative">
            <div class="relative z-10">
                <h1 class="text-2xl md:text-3xl font-bold text-white mb-2 text-shadow">{{format_title title}}</h1>
                <div class="h-1 w-20 bg-white rounded-full opacity-75"></div>
            </div>
            <!-- Optional decorative elements -->
            <div class="absolute bottom-0 right-0 transform translate-y-1/2 translate-x-1/4 w-64 h-64 bg-white/10 rounded-full blur-xl"></div>
            <div class="absolute top-0 left-0 transform -translate-y-1/2 -translate-x-1/4 w-48 h-48 bg-white/10 rounded-full blur-lg"></div>
        </div>

        <!-- Content Container with new padding -->
        <div class="p-6">
            <!-- Summary Section -->
            <div class="bg-blue-50 rounded-lg p-6 mb-8">
                <h2 class="text-lg font-semibold text-blue-800 mb-2">Summary</h2>
                <p class="text-gray-700 leading-relaxed">
                    {{{nl2br_with_code summary}}}
                </p>
            </div>

            <!-- Messages Section -->
            <div class="space-y-6">
                {{#each messages}}
                <div class="rounded-lg {{#if (eq this.role 'user')}}bg-gray-50{{else}}bg-green-50{{/if}} p-4">
                    <!-- Role Badge -->
                    <div class="flex items-center mb-2">
                        <span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium 
                            {{#if (eq this.role 'user')}}
                                bg-gray-200 text-gray-800
                            {{else}}
                                bg-green-200 text-green-800
                            {{/if}}">
                            {{this.role}}
                        </span>
                    </div>

                    <!-- Message Content -->
                    <div class="prose max-w-none">
                        {{{nl2br_with_code content}}}
                    </div>
                </div>
                {{/each}}
            </div>

            <!-- Timestamp -->
            <div class="mt-8 text-sm text-gray-500 text-right">
                Generated: {{timestamp}}
            </div>
        </div>
    </div>
    <script>
    // This script generates the Copy button for the code.
    document.addEventListener('DOMContentLoaded', () => {
        // Find all pre elements and wrap them
        document.querySelectorAll('pre').forEach(pre => {
            // Create wrapper
            const wrapper = document.createElement('div');
            wrapper.className = 'code-wrapper';
            
            // Create copy button
            const copyButton = document.createElement('button');
            copyButton.className = 'copy-button focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500';
            copyButton.innerHTML = `
                <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
                          d="M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3">
                    </path>
                </svg>
                Copy
            `;
            
            // Add click handler
            copyButton.addEventListener('click', async () => {
                const code = pre.querySelector('code');
                const originalText = copyButton.innerHTML;
                
                try {
                    await navigator.clipboard.writeText(code.innerText);
                    copyButton.innerHTML = `
                        <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
                                  d="M5 13l4 4L19 7">
                            </path>
                        </svg>
                        Copied!
                    `;
                    copyButton.classList.add('bg-green-100', 'text-green-800');
                    
                    setTimeout(() => {
                        copyButton.innerHTML = originalText;
                        copyButton.classList.remove('bg-green-100', 'text-green-800');
                    }, 2000);
                } catch (err) {
                    console.error('Failed to copy:', err);
                    copyButton.textContent = 'Error!';
                    setTimeout(() => {
                        copyButton.innerHTML = originalText;
                    }, 2000);
                }
            });
            
            // Insert the button and wrap the pre
            pre.parentNode.insertBefore(wrapper, pre);
            wrapper.appendChild(pre);
            wrapper.appendChild(copyButton);
        });

        // Initialize Prism
        Prism.highlightAll();
    });
    </script>

    <!-- Add Prism.js script -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-core.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
</body>
</html>