feat(chat): use Streamdown for markdown rendering in chat messages
- Add streamdown package for AI-optimized markdown streaming - Update dashboard and public agent chat pages to render messages with Streamdown - Enables proper markdown formatting (code blocks, lists, etc.) in chat responses
This commit is contained in:
parent
27e7d45646
commit
1c903cd26e
5 changed files with 252 additions and 5 deletions
|
|
@ -8,6 +8,7 @@ import Link from 'next/link';
|
|||
import { useParams, useRouter } from 'next/navigation';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { Virtuoso, type VirtuosoHandle } from 'react-virtuoso';
|
||||
import { Streamdown } from 'streamdown';
|
||||
import { AppHeader } from '~/components/AppHeader';
|
||||
import { LikeButton } from '~/components/LikeButton';
|
||||
|
||||
|
|
@ -807,7 +808,9 @@ export default function PublicAgentChatPage(): React.ReactElement {
|
|||
{streamingContent && (
|
||||
<div className="flex justify-start">
|
||||
<div className="max-w-[80%] rounded-lg p-4 bg-surface-secondary">
|
||||
<p className="whitespace-pre-wrap text-sm">{streamingContent}</p>
|
||||
<div className="text-sm prose prose-sm dark:prose-invert max-w-none">
|
||||
<Streamdown>{streamingContent}</Streamdown>
|
||||
</div>
|
||||
<span className="inline-block w-2 h-4 bg-primary animate-pulse ml-1" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -884,7 +887,9 @@ export default function PublicAgentChatPage(): React.ReactElement {
|
|||
{message.role === 'USER' && (
|
||||
<div className="flex justify-end">
|
||||
<div className="max-w-[80%] rounded-lg p-4 bg-primary text-primary-foreground">
|
||||
<p className="whitespace-pre-wrap text-sm">{message.content}</p>
|
||||
<div className="text-sm prose prose-sm prose-invert max-w-none">
|
||||
<Streamdown>{message.content}</Streamdown>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -896,7 +901,9 @@ export default function PublicAgentChatPage(): React.ReactElement {
|
|||
{message.content && (
|
||||
<div className="flex justify-start">
|
||||
<div className="max-w-[80%] rounded-lg p-4 bg-surface-secondary">
|
||||
<p className="whitespace-pre-wrap text-sm">{message.content}</p>
|
||||
<div className="text-sm prose prose-sm dark:prose-invert max-w-none">
|
||||
<Streamdown>{message.content}</Streamdown>
|
||||
</div>
|
||||
{/* Token usage for debugging */}
|
||||
{(message.inputTokens || message.outputTokens) && (
|
||||
<div className="mt-2 pt-2 border-t border-border/50 text-[10px] text-foreground-tertiary font-mono">
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { Icon } from '@tpmjs/ui/Icon/Icon';
|
|||
import Link from 'next/link';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { Streamdown } from 'streamdown';
|
||||
import { DashboardLayout } from '~/components/dashboard/DashboardLayout';
|
||||
|
||||
interface Agent {
|
||||
|
|
@ -678,7 +679,9 @@ export default function AgentChatPage(): React.ReactElement {
|
|||
: 'bg-surface-secondary'
|
||||
}`}
|
||||
>
|
||||
<p className="whitespace-pre-wrap text-sm">{message.content}</p>
|
||||
<div className="text-sm prose prose-sm dark:prose-invert max-w-none">
|
||||
<Streamdown>{message.content}</Streamdown>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -707,7 +710,9 @@ export default function AgentChatPage(): React.ReactElement {
|
|||
{streamingContent && (
|
||||
<div className="flex justify-start">
|
||||
<div className="max-w-[80%] rounded-lg p-4 bg-surface-secondary">
|
||||
<p className="whitespace-pre-wrap text-sm">{streamingContent}</p>
|
||||
<div className="text-sm prose prose-sm dark:prose-invert max-w-none">
|
||||
<Streamdown>{streamingContent}</Streamdown>
|
||||
</div>
|
||||
<span className="inline-block w-2 h-4 bg-primary animate-pulse ml-1" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue