fix: improve assistant thinking and image progress
This commit is contained in:
@@ -112,6 +112,9 @@ const QUICK_PROMPTS = [
|
||||
'根据已有角色和场景,继续生成 ComfyUI 工作流 JSON',
|
||||
];
|
||||
|
||||
const STREAMING_REASONING_PLACEHOLDER = '正在等待模型返回真实思考过程,收到后会实时替换这里。';
|
||||
const STREAMING_BODY_PLACEHOLDER = '模型正在组织正文和素材步骤...';
|
||||
|
||||
const SEEDANCE_PROMPT_TEMPLATES = [
|
||||
{
|
||||
title: '文生视频',
|
||||
@@ -651,7 +654,7 @@ function renderMarkdown(content: string): string {
|
||||
}
|
||||
|
||||
function processThinkTags(content: string, reasoningContent = '') {
|
||||
if (!content.includes('<think>')) {
|
||||
if (!content || !/<think>/i.test(content)) {
|
||||
return { content, reasoningContent };
|
||||
}
|
||||
const thoughts: string[] = [];
|
||||
@@ -665,7 +668,18 @@ function processThinkTags(content: string, reasoningContent = '') {
|
||||
lastIndex = match.index + match[0].length;
|
||||
}
|
||||
replyParts.push(content.substring(lastIndex));
|
||||
const cleanContent = replyParts.join('').replace(/<\/?think>/gi, '').trim();
|
||||
|
||||
let cleanContent = replyParts.join('');
|
||||
const lastOpenThinkIndex = cleanContent.toLowerCase().lastIndexOf('<think>');
|
||||
if (lastOpenThinkIndex !== -1) {
|
||||
const fragmentAfterLastOpen = cleanContent.substring(lastOpenThinkIndex + '<think>'.length);
|
||||
if (!/<\/think>/i.test(fragmentAfterLastOpen)) {
|
||||
thoughts.push(fragmentAfterLastOpen.trim());
|
||||
cleanContent = cleanContent.substring(0, lastOpenThinkIndex);
|
||||
}
|
||||
}
|
||||
|
||||
cleanContent = cleanContent.replace(/<\/?think>/gi, '').trim();
|
||||
const thoughtsText = thoughts.filter(Boolean).join('\n\n---\n\n');
|
||||
return {
|
||||
content: cleanContent,
|
||||
@@ -821,7 +835,7 @@ export default function ComfyUIAgent() {
|
||||
|
||||
useEffect(() => {
|
||||
chatEndRef.current?.scrollIntoView({ behavior: 'smooth', block: 'end' });
|
||||
}, [messages, streaming?.content]);
|
||||
}, [messages, streaming?.content, streaming?.reasoningContent, streaming?.images.length, streaming?.scenes.length, streaming?.tts.length]);
|
||||
|
||||
useEffect(() => {
|
||||
activeConversationIdRef.current = activeConversationId;
|
||||
@@ -1349,16 +1363,30 @@ export default function ComfyUIAgent() {
|
||||
const renderReasoning = (message: AgentMessage | StreamAccumulator, isStreaming = false) => {
|
||||
const processed = processThinkTags(message.content || '', message.reasoningContent || '');
|
||||
const hasReasoning = processed.reasoningContent.trim().length > 0;
|
||||
if (!hasReasoning) return null;
|
||||
if (!hasReasoning && !isStreaming) return null;
|
||||
return (
|
||||
<details open={isStreaming} style={reasoningBoxStyle}>
|
||||
<details
|
||||
open={isStreaming}
|
||||
style={{
|
||||
...reasoningBoxStyle,
|
||||
...(!hasReasoning && isStreaming ? reasoningPendingBoxStyle : {}),
|
||||
}}
|
||||
>
|
||||
<summary style={reasoningSummaryStyle}>
|
||||
思考过程
|
||||
<span>思考过程</span>
|
||||
{isStreaming ? <em style={reasoningLiveBadgeStyle}>实时</em> : null}
|
||||
</summary>
|
||||
<div
|
||||
style={reasoningContentStyle}
|
||||
dangerouslySetInnerHTML={{ __html: renderMarkdown(processed.reasoningContent) }}
|
||||
/>
|
||||
{hasReasoning ? (
|
||||
<div
|
||||
style={reasoningContentStyle}
|
||||
dangerouslySetInnerHTML={{ __html: renderMarkdown(processed.reasoningContent) }}
|
||||
/>
|
||||
) : (
|
||||
<div style={reasoningPendingStyle}>
|
||||
<span style={reasoningPulseDotStyle} />
|
||||
<span>{STREAMING_REASONING_PLACEHOLDER}</span>
|
||||
</div>
|
||||
)}
|
||||
</details>
|
||||
);
|
||||
};
|
||||
@@ -1711,6 +1739,9 @@ export default function ComfyUIAgent() {
|
||||
{renderReasoning(streaming, true)}
|
||||
{streaming.content ? renderMessageContent(streaming) : null}
|
||||
{streaming.content ? <span style={cursorStyle}>|</span> : null}
|
||||
{!streaming.content && !streaming.images.length && !streaming.scenes.length && !streaming.tts.length ? (
|
||||
<div style={streamingBodyStatusStyle}>{STREAMING_BODY_PLACEHOLDER}</div>
|
||||
) : null}
|
||||
{renderAssets(streaming)}
|
||||
<div style={messageActionsStyle}>
|
||||
<button
|
||||
@@ -2121,6 +2152,9 @@ const reasoningSummaryStyle: CSSProperties = {
|
||||
fontSize: 12,
|
||||
fontWeight: 700,
|
||||
color: 'var(--color-primary)',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 6,
|
||||
};
|
||||
|
||||
const reasoningContentStyle: CSSProperties = {
|
||||
@@ -2130,6 +2164,57 @@ const reasoningContentStyle: CSSProperties = {
|
||||
color: 'var(--color-text-secondary)',
|
||||
};
|
||||
|
||||
const reasoningPendingBoxStyle: CSSProperties = {
|
||||
borderStyle: 'dashed',
|
||||
background:
|
||||
'linear-gradient(135deg, color-mix(in srgb, var(--color-primary) 7%, var(--color-bg)), color-mix(in srgb, var(--color-info) 5%, var(--color-bg)))',
|
||||
};
|
||||
|
||||
const reasoningLiveBadgeStyle: CSSProperties = {
|
||||
marginLeft: 8,
|
||||
padding: '1px 6px',
|
||||
border: '1px solid color-mix(in srgb, var(--color-primary) 22%, var(--color-border-light))',
|
||||
borderRadius: 999,
|
||||
color: 'var(--color-primary)',
|
||||
background: 'color-mix(in srgb, var(--color-primary) 8%, transparent)',
|
||||
fontSize: 11,
|
||||
fontStyle: 'normal',
|
||||
fontWeight: 700,
|
||||
};
|
||||
|
||||
const reasoningPendingStyle: CSSProperties = {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 8,
|
||||
padding: '0 10px 10px',
|
||||
color: 'var(--color-text-muted)',
|
||||
fontSize: 12,
|
||||
lineHeight: 1.6,
|
||||
};
|
||||
|
||||
const reasoningPulseDotStyle: CSSProperties = {
|
||||
width: 7,
|
||||
height: 7,
|
||||
flexShrink: 0,
|
||||
borderRadius: 999,
|
||||
background: 'var(--color-primary)',
|
||||
boxShadow: '0 0 0 5px color-mix(in srgb, var(--color-primary) 12%, transparent)',
|
||||
};
|
||||
|
||||
const streamingBodyStatusStyle: CSSProperties = {
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
width: 'fit-content',
|
||||
maxWidth: '100%',
|
||||
marginTop: 4,
|
||||
padding: '7px 10px',
|
||||
border: '1px solid var(--color-border-light)',
|
||||
borderRadius: 999,
|
||||
background: 'color-mix(in srgb, var(--color-bg) 74%, var(--color-surface))',
|
||||
color: 'var(--color-text-muted)',
|
||||
fontSize: 12,
|
||||
};
|
||||
|
||||
const inputBarStyle: CSSProperties = {
|
||||
padding: 16,
|
||||
borderTop: '1px solid var(--color-border)',
|
||||
|
||||
Reference in New Issue
Block a user