Spaces:
Sleeping
Sleeping
Download frontend/src/components/ResponseBlock.js from neongeckocom/LLM_Comparison_Tool: direct link, hf CLI and curl.
- Browser
- Download file 7.73 kB
-
https://huggingface.co/spaces/neongeckocom/LLM_Comparison_Tool/resolve/main/frontend/src/components/ResponseBlock.js
- Command line
-
hf download hf://spaces/neongeckocom/LLM_Comparison_Tool/frontend/src/components/ResponseBlock.js
-
curl -L -o ResponseBlock.js https://huggingface.co/spaces/neongeckocom/LLM_Comparison_Tool/resolve/main/frontend/src/components/ResponseBlock.js
7.73 kB
| import ReactMarkdown from 'react-markdown'; | |
| import remarkGfm from 'remark-gfm'; | |
| import { Clock, Server } from 'lucide-react'; | |
| import { neonModelDisplayName, neonPersonaDisplayName } from '../utils/displayName'; | |
| export default function ResponseBlock({ | |
| response, | |
| isNeonEmphasis = false, | |
| isComparisonEmphasis = false, | |
| showBadge = false, | |
| showModelName = true, | |
| showPersona = false, | |
| showFooterParams = true, | |
| showPrePromptIndicator = false, | |
| }) { | |
| const personaText = response.persona_name && response.is_neon | |
| ? neonPersonaDisplayName(response.persona_name) | |
| : null; | |
| const displayModelName = response.is_neon | |
| ? neonModelDisplayName(response.model_name || response.model_id) | |
| : response.model_name; | |
| const hasHeader = showModelName || showBadge; | |
| const emphasisClass = isNeonEmphasis ? 'neon-emphasis' : (isComparisonEmphasis ? 'comp-emphasis' : ''); | |
| return ( | |
| <div className={`response-block ${emphasisClass}`}> | |
| {hasHeader && ( | |
| <div className="response-header"> | |
| <div className="response-model-info"> | |
| {showModelName && ( | |
| <span className="response-model-name"> | |
| {displayModelName} | |
| {showPersona && personaText && ( | |
| <span className="response-persona-inline"> · {personaText}</span> | |
| )} | |
| </span> | |
| )} | |
| </div> | |
| </div> | |
| )} | |
| <div className="response-body"> | |
| {response.error ? ( | |
| <div className="response-error">{response.response}</div> | |
| ) : ( | |
| <ReactMarkdown remarkPlugins={[remarkGfm]}>{response.response}</ReactMarkdown> | |
| )} | |
| </div> | |
| <div className="response-footer"> | |
| <div className="response-timing"> | |
| <Clock size={12} /> | |
| {response.elapsed_seconds}s | |
| </div> | |
| {showPrePromptIndicator ? ( | |
| <div className={`response-specs ${response.has_persona ? 'preprompt-yes' : 'preprompt-no'}`}> | |
| <span className="spec-value"> | |
| {response.has_persona ? 'With pre-prompt' : 'No pre-prompt'} | |
| </span> | |
| </div> | |
| ) : showFooterParams ? ( | |
| <div className="response-specs"> | |
| <Server size={12} /> | |
| <span className={response.params ? 'spec-value' : 'spec-placeholder'}> | |
| {response.params ? `Params: ${response.params}` : 'Model size: TBD'} | |
| </span> | |
| </div> | |
| ) : null} | |
| </div> | |
| <style>{` | |
| .response-block { | |
| border: 1px solid var(--border-primary); | |
| border-radius: 12px; | |
| background: var(--card-bg); | |
| box-shadow: var(--shadow-sm); | |
| overflow: hidden; | |
| display: flex; | |
| flex-direction: column; | |
| min-width: 0; | |
| width: 100%; | |
| max-width: 100%; | |
| flex: 1; | |
| transition: box-shadow 0.2s; | |
| } | |
| .response-block:hover { | |
| box-shadow: var(--shadow-md); | |
| } | |
| .response-block.neon-emphasis { | |
| border-color: var(--border-primary); | |
| border-left: 3px solid var(--neon-accent); | |
| box-shadow: var(--shadow-sm); | |
| } | |
| .response-block.neon-emphasis .response-header { | |
| background: var(--card-bg); | |
| border-bottom: 1px solid var(--border-muted); | |
| } | |
| .response-block.comp-emphasis { | |
| border-color: var(--border-primary); | |
| border-left: 3px solid var(--comp-border); | |
| box-shadow: var(--shadow-sm); | |
| } | |
| .response-block.comp-emphasis .response-header { | |
| background: var(--card-bg); | |
| border-bottom: 1px solid var(--border-muted); | |
| } | |
| .response-header { | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| padding: 10px 14px; | |
| background: var(--card-bg); | |
| border-bottom: 1px solid var(--border-muted); | |
| gap: 8px; | |
| } | |
| .response-model-info { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| min-width: 0; | |
| } | |
| .response-model-name { | |
| font-size: 14px; | |
| font-weight: 600; | |
| color: var(--text-primary); | |
| overflow: hidden; | |
| text-overflow: ellipsis; | |
| white-space: nowrap; | |
| } | |
| .response-persona-inline { | |
| font-weight: 400; | |
| color: var(--text-muted); | |
| font-size: 13px; | |
| } | |
| .response-body { | |
| padding: 14px 16px; | |
| font-size: 15px; | |
| line-height: 1.55; | |
| color: var(--text-primary); | |
| flex: 1; | |
| overflow-y: auto; | |
| overflow-x: auto; | |
| max-height: 400px; | |
| min-width: 0; | |
| overflow-wrap: anywhere; | |
| word-break: break-word; | |
| } | |
| .response-body h1, .response-body h2, .response-body h3 { | |
| color: var(--text-primary); | |
| margin: 12px 0 6px; | |
| } | |
| .response-body h3 { font-size: 15px; } | |
| .response-body p { margin-bottom: 8px; } | |
| .response-body ul, .response-body ol { | |
| padding-left: 20px; | |
| margin-bottom: 8px; | |
| } | |
| .response-body li { margin-bottom: 4px; } | |
| .response-body code { | |
| font-size: 12px; | |
| padding: 1px 4px; | |
| border-radius: 4px; | |
| background: var(--bg-tertiary); | |
| font-family: 'Fira Code', 'Consolas', monospace; | |
| } | |
| .response-body pre { | |
| padding: 10px; | |
| border-radius: 8px; | |
| background: var(--bg-tertiary); | |
| overflow-x: auto; | |
| margin-bottom: 8px; | |
| } | |
| .response-body pre code { | |
| padding: 0; | |
| background: none; | |
| } | |
| .response-body strong { | |
| color: var(--text-primary); | |
| font-weight: 600; | |
| } | |
| .response-error { | |
| color: #EF4444; | |
| font-style: italic; | |
| } | |
| .response-footer { | |
| padding: 8px 14px; | |
| border-top: 1px solid var(--border-muted); | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| font-size: 11px; | |
| color: var(--text-muted); | |
| flex-wrap: wrap; | |
| gap: 4px; | |
| } | |
| .response-timing { | |
| display: flex; | |
| align-items: center; | |
| gap: 4px; | |
| font-weight: 500; | |
| } | |
| .response-specs { | |
| display: flex; | |
| align-items: center; | |
| gap: 4px; | |
| } | |
| .spec-placeholder { | |
| font-style: italic; | |
| } | |
| .spec-value { | |
| font-weight: 500; | |
| color: var(--text-secondary); | |
| } | |
| .preprompt-yes .spec-value { | |
| color: var(--accent-primary); | |
| font-weight: 600; | |
| } | |
| .preprompt-no .spec-value { | |
| color: var(--text-muted); | |
| font-style: italic; | |
| } | |
| @media (max-width: 900px) { | |
| .response-block { | |
| min-width: 0; | |
| } | |
| .response-body { | |
| max-height: 300px; | |
| padding: 12px; | |
| } | |
| } | |
| @media (max-width: 480px) { | |
| .response-body { | |
| max-height: none; | |
| font-size: 13px; | |
| padding: 10px; | |
| } | |
| .response-header { | |
| padding: 8px 10px; | |
| } | |
| .response-footer { | |
| padding: 6px 10px; | |
| } | |
| } | |
| `}</style> | |
| </div> | |
| ); | |
| } | |