/** * Host half of the html-preview bundle: the model-facing `render_html` tool. * * The tool owns no rendering. It validates one HTML snippet, records its size, * and hands the caller a receipt small enough to keep out of the model's way — * the markup itself travels in the recorded `tool/call` arguments, which the * browser reads directly through the `render_html` tool view. * @module dsh-html-live-preview */ import { defineTool } from '@deepseek-ai/dsh-tools'; /** Stable Loader identity. */ export const name = 'html-preview'; /** Services used by the tool row. */ export const inject = ['tools']; /** Largest accepted snippet, in characters (a session-log and context guard). */ const MAX_HTML_CHARS = 256 * 1024; /** * Shorten one line of model text for a card title. * @param value - candidate title, however malformed. * @returns the trimmed single line, or undefined when nothing usable remains. */ function normalizeTitle(value) { if (typeof value !== 'string') return undefined; const line = value.replace(/\s+/g, ' ').trim(); if (line.length === 0) return undefined; return line.length > 120 ? `${line.slice(0, 117)}...` : line; } /** Human-readable character count for the model-facing receipt. */ function describeSize(characters) { return characters >= 1024 ? `${(characters / 1024).toFixed(1)} KiB` : `${characters} chars`; } /** * Register `render_html` in the tools registry of the mounting scope. * @param ctx - mounting context carrying the tools registry. */ export function apply(ctx) { ctx.tools.register(defineTool({ name: 'render_html', description: [ 'Render an HTML/CSS/JS snippet as a live, interactive preview inside the conversation.', 'The user watches it appear while you are still writing the arguments, so prefer this tool over a fenced ```html block in your reply whenever the result is visual: diagrams, charts, dashboards, UI mockups, animations, 3D scenes, geometry or math illustrations, styled tables, and any "show me what this looks like" request.', '', 'How to write the snippet:', '- `html` is a FRAGMENT. Do not wrap it in , ,
, or ; a full document is also accepted but the wrapper is discarded.', '- Write the structure and