refactor: streamline handling of <details> tags in markdown parsing

- Updated the assistant message widget to rely on the markdown parser for <details> tags, eliminating manual tag management for tool_calls and reasoning types.
- Enhanced the details builder to ensure proper handling of <details> elements during streaming, preventing character flashing.
- Cleaned up the code by removing redundant comments and consolidating logic for improved readability and maintainability.
This commit is contained in:
cogwheel0
2025-10-05 23:43:50 +05:30
parent 661a32866f
commit 9dd27bb4e5
2 changed files with 13 additions and 27 deletions

View File

@@ -720,26 +720,14 @@ class _AssistantMessageWidgetState extends ConsumerState<AssistantMessageWidget>
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
// Always hide tool_calls blocks; tiles render them separately. // Note: The markdown parser now handles <details> tags (including type="reasoning"
String cleaned = content.replaceAll( // and type="tool_calls") via a custom block syntax, so they won't be rendered as
RegExp( // plain text during streaming. This prevents character flashing.
r'<details\s+type="tool_calls"[^>]*>[\s\S]*?<\/details>',
multiLine: true, // We still clean raw reasoning tags (<think>, <reasoning>) as a fallback.
dotAll: true, // The server normally converts these to <details> format, but raw mode or
), // direct API responses might still use them.
'', String cleaned = content
);
// Also hide reasoning details blocks if any slipped into text
cleaned = cleaned.replaceAll(
RegExp(
r'<details\s+type="reasoning"[^>]*>[\s\S]*?<\/details>',
multiLine: true,
dotAll: true,
),
'',
);
// Remove raw <think>...</think> or <reasoning>...</reasoning> tags in text
cleaned = cleaned
.replaceAll( .replaceAll(
RegExp(r'<think>[\s\S]*?<\/think>', multiLine: true, dotAll: true), RegExp(r'<think>[\s\S]*?<\/think>', multiLine: true, dotAll: true),
'', '',
@@ -753,10 +741,6 @@ class _AssistantMessageWidgetState extends ConsumerState<AssistantMessageWidget>
'', '',
); );
// Note: The markdown parser now handles <details> tags via a custom block syntax,
// so they won't be rendered as plain text during streaming. This prevents the
// character flashing issue.
// Process images in the remaining text // Process images in the remaining text
final processedContent = _processContentForImages(cleaned); final processedContent = _processContentForImages(cleaned);

View File

@@ -763,9 +763,11 @@ class _DetailsBuilder extends MarkdownElementBuilder {
@override @override
Widget? visitElementAfter(md.Element element, TextStyle? preferredStyle) { Widget? visitElementAfter(md.Element element, TextStyle? preferredStyle) {
// The details element should not be rendered as markdown during streaming. // Details elements with type="reasoning" or type="tool_calls" should not be
// Instead, it's handled by the ReasoningParser in assistant_message_widget. // rendered as markdown during streaming. They are handled by:
// Return empty widget to prevent flashing. // - ReasoningParser for reasoning blocks (creates thinking tiles)
// - ToolCallsParser for tool_calls blocks (creates tool execution tiles)
// Return empty widget to prevent character flashing during streaming.
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
} }