-
❓ .gitignoreUnknown, 37 B⬇
-
❓ README.mdUnknown, 2.94 kB⬇
-
🌐 admin_panel.phpWeb, 1.54 kB⬇
-
🌐 api.jsWeb, 22.21 kB⬇
-
🌐 api.phpWeb, 9.62 kB⬇
-
🌐 app.jsWeb, 61.42 kB⬇
-
🌐 attachments.jsWeb, 7.30 kB⬇
-
🌐 base.cssWeb, 2.23 kB⬇
-
🌐 choices-editor.jsWeb, 28.11 kB⬇
-
🌐 choices.cssWeb, 1.14 kB⬇
-
🌐 content.jsWeb, 31.08 kB⬇
-
🌐 context.jsWeb, 9.26 kB⬇
-
🌐 conversation-index.jsWeb, 10.74 kB⬇
-
🌐 conversation.cssWeb, 16.33 kB⬇
-
🌐 conversation.jsWeb, 1.11 kB⬇
-
🌐 dialogs.cssWeb, 11.43 kB⬇
-
🌐 diction.jsWeb, 948 B⬇
-
🌐 document-index.jsWeb, 1.04 kB⬇
-
🌐 document-model.jsWeb, 12.88 kB⬇
-
🌐 document.cssWeb, 6.74 kB⬇
-
🌐 document.jsWeb, 44.96 kB⬇
-
🌐 dynamic.phpWeb, 533 B⬇
-
📷 favicon-lg.pngImage, 9.11 kB⬇
-
📷 favicon.pngImage, 3.12 kB⬇
-
🌐 index-lists.cssWeb, 4.77 kB⬇
-
🌐 index.phpWeb, 49.72 kB⬇
-
🌐 indexjs.jsWeb, 377 B⬇
-
🌐 instant-answer.cssWeb, 5.17 kB⬇
-
🌐 layout.cssWeb, 11.37 kB⬇
-
🌐 login.phpWeb, 997 B⬇
-
❓ manifest.webmanifestUnknown, 262 B⬇
-
🌐 memory.jsWeb, 407 B⬇
-
🌐 mermaid.cssWeb, 6.16 kB⬇
-
🌐 model-presets.jsonWeb, 5.51 kB⬇
-
🌐 models.jsonWeb, 8.05 kB⬇
-
🌐 notes.cssWeb, 11.97 kB⬇
-
🌐 overlays.cssWeb, 13.97 kB⬇
-
⚠️ php.iniOS File, 424 B⬇
-
🌐 rankings-view.jsWeb, 5.67 kB⬇
-
🌐 rankings.cssWeb, 3.35 kB⬇
-
🌐 scratchpad-conversation.jsWeb, 4.87 kB⬇
-
🌐 scratchpad-index.jsWeb, 15.55 kB⬇
-
🌐 scratchpad-model.jsWeb, 13.29 kB⬇
-
🌐 scratchpad.cssWeb, 3.12 kB⬇
-
🌐 settings.cssWeb, 4.65 kB⬇
-
🌐 shared-view.cssWeb, 3.48 kB⬇
-
🌐 shared.cssWeb, 16.26 kB⬇
-
🌐 shared.jsWeb, 14.63 kB⬇
-
🌐 shared.phpWeb, 3.28 kB⬇
-
🌐 sticky-notes-editor.jsWeb, 64.84 kB⬇
-
🌐 storage.jsWeb, 36.73 kB⬇
-
🌐 style.cssWeb, 12.06 kB⬇
-
🌐 sw.jsWeb, 1.69 kB⬇
-
🌐 sync.jsWeb, 19.02 kB⬇
-
🌐 tools-index.jsWeb, 15.00 kB⬇
-
🌐 users.jsWeb, 49.86 kB⬇
-
🌐 utility-models.jsonWeb, 1.04 kB⬇
-
🌐 voice-models.jsonWeb, 4.81 kB⬇
import {
formatContentBlock,
formatAnnotationsBlock,
formatSuggestions,
formatCostSummary
} from './util/conversation-format-utils.js';
import { formatThinkingBlockHtml } from './util/format-utils.js';
/**
* Class ScratchpadConversation
* Handles formatting and rendering specifically for scratchpad conversation
* revisions. Each history entry is a revision holding the full scratchpad
* state (items with guids, table of contents, changes); only the most recent
* revision is displayed, and pending revisions render live so tool-driven
* edits appear as they apply.
*/
class ScratchpadConversation {
/**
* Initializes a new instance of ScratchpadConversation.
*/
constructor() {
}
/**
* Formats a single scratchpad revision as HTML.
* @param {Object} data - The revision (history item) data.
* @param {number} index - The index of the revision in history.
* @param {Object} [conversation_settings={}] - Settings for the conversation.
* @returns {string} The formatted HTML string.
*/
format_scratchpad_item(data, index, conversation_settings = {}) {
if (!data) return '';
let html = '';
if (!data.pending) {
html += this.format_scratchpad_header(index, !!conversation_settings.read_only);
}
html += formatThinkingBlockHtml(data.thinking, !!data.pending, index);
const items = Array.isArray(data.items) ? data.items : (Array.isArray(data.content) ? data.content : []);
let response_html = formatContentBlock(items);
response_html += formatAnnotationsBlock(data.annotations);
html += `<div class="div-response-content" data-index="${index}">${response_html}</div>`;
if (data.pending) {
return html;
}
html += formatSuggestions(data, conversation_settings);
html += formatCostSummary(data);
return html;
}
/**
* Formats the scratchpad revision header toolbar.
* @param {number} index - The index of the revision in history.
* @param {boolean} [read_only=false] - When true, renders only the Copy
* button (used by the shared viewer).
* @returns {string} The toolbar HTML string.
*/
format_scratchpad_header(index, read_only = false) {
const left_buttons = '<button class="btn-copy-scratchpad btn-compact" data-index="' + index + '">Copy</button>';
if (read_only) {
return `
<div class="div-chat-response-buttons div-chat-scratchpad-buttons">
<div class="div-chat-response-buttons-left">${left_buttons}</div>
</div>
`;
}
return `
<div class="div-chat-response-buttons div-chat-scratchpad-buttons">
<div class="div-chat-response-buttons-left">${left_buttons}</div>
<div class="div-chat-read-controls">
<button class="btn-read-prev btn-compact as-icon" data-index="${index}" title="Previous item">⏮</button>
<button class="btn-read-toggle btn-compact as-icon" data-index="${index}" title="Read aloud">▶</button>
<button class="btn-read-next btn-compact as-icon" data-index="${index}" title="Next item">⏯</button>
<label class="label-sync-switch label-read-option" title="Auto-advance">
<input type="checkbox" class="input-read-auto" role="switch" aria-label="Auto-advance">
<span class="span-sync-switch"></span>
<span class="span-read-repeat as-icon" aria-hidden="true">🔁</span>
</label>
<label class="label-sync-switch label-read-option" title="Auto-play new replies">
<input type="checkbox" class="input-read-autoplay" role="switch" aria-label="Auto-play new replies">
<span class="span-sync-switch"></span>
<span class="span-read-repeat as-icon" aria-hidden="true">⏺︎</span>
</label>
<span class="span-read-loading index-item-indicator as-icon" data-index="${index}" style="display: none;" title="Loading audio...">●</span>
</div>
<div class="div-chat-response-buttons-right">
<button class="btn-redo-scratchpad btn-compact" data-index="${index}">Redo</button>
<button class="btn-undo-scratchpad btn-compact" data-index="${index}">Undo</button>
<button class="btn-delete-scratchpad btn-compact" data-index="${index}">Delete</button>
</div>
</div>
`;
}
/**
* Renders the scratchpad, displaying only the most recent revision.
* @param {Object} conversation - The conversation object containing HISTORY array.
* @param {Object} [options={}] - Render options (e.g. show_suggested, show_related).
* @returns {string} The complete HTML string for the scratchpad conversation.
*/
render(conversation, options = {}) {
if (!conversation) return '<p>Enter a query to get started.</p>';
const history = conversation.HISTORY || conversation.history || (Array.isArray(conversation) ? conversation : []);
if (!Array.isArray(history) || history.length === 0) return '<p>Enter a query to get started.</p>';
const lastIndex = history.length - 1;
const lastItem = history[lastIndex];
return this.format_scratchpad_item(lastItem, lastIndex, options);
}
}
export default ScratchpadConversation;
scratchpad-conversation.js
×
Type: Web, text/plain
4.87 Kilobytes
Last Modified 2026-11-04 09:48:28
⬇ Download File
Type: Web, text/plain
4.87 Kilobytes
Last Modified 2026-11-04 09:48:28
⬇ Download File