feat: thinking blocks collapsed by default [appimage]
Some checks failed
Build AppImage / build (push) Has been cancelled
Some checks failed
Build AppImage / build (push) Has been cancelled
- Extended Thinking (SDK thinking blocks) rendered as collapsible
<details> elements — closed by default, click to expand
- Text-based thinking patterns (Lass mich..., Ich analysiere...)
auto-detected and wrapped in collapsible block
- Clean styling: subtle border, smaller font, 💭 icon
- Bridge now forwards thinking content blocks (previously ignored)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
8a7e0d87f3
commit
8336ac6eb1
2 changed files with 63 additions and 1 deletions
|
|
@ -542,6 +542,12 @@ async function sendMessage(message, requestId, model = null, contextOverride = n
|
|||
if (block.type === 'text' && block.text) {
|
||||
fullText += block.text;
|
||||
sendEvent('text', { text: block.text });
|
||||
} else if (block.type === 'thinking' && block.thinking) {
|
||||
// Extended Thinking — als kollabierbaren Block senden
|
||||
const thinkLines = block.thinking.split('\n').length;
|
||||
const collapsed = `<details class="thinking-block"><summary>💭 Überlegung (${thinkLines} Zeilen)</summary>\n\n${block.thinking}\n\n</details>\n\n`;
|
||||
fullText += collapsed;
|
||||
sendEvent('text', { text: collapsed });
|
||||
} else if (block.type === 'tool_use') {
|
||||
// Tool-Call von Main-Agent — manuell weiterreichen, damit
|
||||
// der tool_use-Case weiter unten greift
|
||||
|
|
|
|||
|
|
@ -42,12 +42,38 @@
|
|||
|
||||
function renderMarkdown(text: string): string {
|
||||
try {
|
||||
return marked.parse(text) as string;
|
||||
// Thinking-Blöcke erkennen und in <details> packen
|
||||
const processed = collapseThinkingBlocks(text);
|
||||
return marked.parse(processed) as string;
|
||||
} catch {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Erkennt "Denk-Blöcke" im Text und packt sie in Markdown-<details>.
|
||||
* Patterns: Absätze die mit typischen Überlegungs-Phrasen starten,
|
||||
* gefolgt von der eigentlichen Antwort.
|
||||
*/
|
||||
function collapseThinkingBlocks(text: string): string {
|
||||
// Pattern: Text beginnt mit Analyse/Überlegungs-Block, dann kommt die Antwort
|
||||
const thinkingPatterns = [
|
||||
/^((?:(?:Lass mich|Ich (?:schaue|prüfe|analysiere|untersuche|überleg)|OK,? (?:lass|ich)|Gut,? (?:lass|ich)|Hmm|Also|Zunächst|Zuerst).*?\n(?:.*\n)*?))((?:\n(?:#{1,3} |(?:\*\*|Die |Das |Hier |Zusammen|Fertig|Erledigt|✅)).*[\s\S]*))/m,
|
||||
];
|
||||
|
||||
for (const pattern of thinkingPatterns) {
|
||||
const match = text.match(pattern);
|
||||
if (match && match[1] && match[1].split('\n').length > 5) {
|
||||
const thinkingPart = match[1].trim();
|
||||
const answerPart = match[2].trim();
|
||||
const lines = thinkingPart.split('\n').length;
|
||||
return `<details class="thinking-block">\n<summary>💭 Überlegung (${lines} Zeilen)</summary>\n\n${thinkingPart}\n\n</details>\n\n${answerPart}`;
|
||||
}
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
// Svelte Action: Copy-Buttons zu Code-Blöcken hinzufügen
|
||||
function addCopyButtons(node: HTMLElement) {
|
||||
function processCodeBlocks() {
|
||||
|
|
@ -1324,6 +1350,36 @@
|
|||
background: var(--bg-hover, #333);
|
||||
}
|
||||
|
||||
/* Thinking-Block (details/summary) */
|
||||
.message-content :global(details.thinking-block) {
|
||||
margin: 0.4rem 0;
|
||||
border: 1px solid var(--border, #3a3a3a);
|
||||
border-radius: 4px;
|
||||
background: var(--bg-tertiary, #1e1e1e);
|
||||
}
|
||||
|
||||
.message-content :global(details.thinking-block summary) {
|
||||
padding: 0.4rem 0.6rem;
|
||||
cursor: pointer;
|
||||
font-size: 0.8rem;
|
||||
color: var(--text-secondary, #888);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.message-content :global(details.thinking-block summary:hover) {
|
||||
color: var(--text-primary, #ccc);
|
||||
}
|
||||
|
||||
.message-content :global(details.thinking-block[open]) {
|
||||
padding-bottom: 0.4rem;
|
||||
}
|
||||
|
||||
.message-content :global(details.thinking-block[open] > :not(summary)) {
|
||||
padding: 0 0.6rem;
|
||||
font-size: 0.8rem;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
/* Markdown-Styles innerhalb von Nachrichten */
|
||||
.message-content :global(p) {
|
||||
margin: 0.3em 0;
|
||||
|
|
|
|||
Loading…
Reference in a new issue