token streaming & reasoning display: live SSE tokens frontend to back
Nightly Build / build (push) Successful in 6m59s
Nightly Build / build (push) Successful in 6m59s
- Add StreamDelta(SseDecoder) framing shared by OpenAI/Anthropic - OpenAiClient: stream=true + reasoning_content deltas, index-based tool_calls accumulation, usage from final chunk - AnthropicClient: message_start/content_block_*/message_delta events, thinking_delta->reasoning, input_json_delta->tool input - TokenDelta ServerEvent variant wired through ChatHub + WS broadcast - Frontend throttled flush (~15 Hz), pending bubble mutate-in-place, reasoning as collapsed-by-default <details> - Drop streaming bubble on error/llm_failed/model_fallback - i18n: chat.reasoning key added to en/fr/it
This commit is contained in:
@@ -88,6 +88,75 @@
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
/* ── Reasoning (chain-of-thought) block ────────────────────────────────────── */
|
||||
/* Small, low-contrast, collapsed by default: visible but never heavy. */
|
||||
|
||||
.reasoning-block {
|
||||
margin: 0 0 0.45rem;
|
||||
font-size: 0.75rem;
|
||||
color: var(--placeholder-color);
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
.reasoning-block > summary {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
font-style: italic;
|
||||
letter-spacing: 0.02em;
|
||||
list-style-position: inside;
|
||||
padding: 0.1rem 0;
|
||||
}
|
||||
|
||||
.reasoning-block > summary:hover {
|
||||
color: var(--msg-assistant-text);
|
||||
}
|
||||
|
||||
.reasoning-block--live > summary {
|
||||
animation: reasoning-pulse 1.6s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.reasoning-content {
|
||||
margin-top: 0.35rem;
|
||||
padding-left: 0.6rem;
|
||||
border-left: 2px solid var(--toolbar-border);
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.72rem;
|
||||
line-height: 1.5;
|
||||
max-height: 16rem;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
@keyframes reasoning-pulse {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.45; }
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.reasoning-block--live > summary { animation: none; }
|
||||
}
|
||||
|
||||
/* Blinking caret at the end of a streaming assistant bubble. */
|
||||
.stream-caret {
|
||||
display: inline-block;
|
||||
width: 0.5em;
|
||||
height: 1em;
|
||||
margin-left: 0.1em;
|
||||
vertical-align: text-bottom;
|
||||
background: currentColor;
|
||||
opacity: 0.6;
|
||||
animation: stream-caret-blink 1s steps(2, start) infinite;
|
||||
}
|
||||
|
||||
@keyframes stream-caret-blink {
|
||||
to { visibility: hidden; }
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.stream-caret { animation: none; }
|
||||
}
|
||||
|
||||
/* ── Tool call blocks ──────────────────────────────────────────────────────── */
|
||||
|
||||
.copilot-tool {
|
||||
|
||||
Reference in New Issue
Block a user