θΏ™ζ˜―indexlocζδΎ›ηš„ζœεŠ‘οΌŒδΈθ¦θΎ“ε…₯任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import React, { useState } from "react";
import {
CaretDown,
CircleNotch,
Check,
CheckCircle,
} from "@phosphor-icons/react";
import { CaretDown } from "@phosphor-icons/react";

import AgentAnimation from "@/media/animations/agent-animation.webm";
import AgentStatic from "@/media/animations/agent-static.png";

export default function StatusResponse({
messages = [],
Expand All @@ -21,94 +19,85 @@ export default function StatusResponse({
}

return (
<div className="flex justify-center items-end w-full">
<div className="py-2 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col relative">
<div
onClick={handleExpandClick}
className={`${!previousThoughts?.length ? "cursor-text" : "cursor-pointer hover:bg-theme-sidebar-item-hover transition-all duration-200"} bg-theme-bg-chat-input rounded-full py-2 px-4 flex items-center gap-x-2 border border-theme-sidebar-border`}
>
{isThinking ? (
<CircleNotch
className="w-4 h-4 text-theme-text-secondary animate-spin"
aria-label="Agent is thinking..."
/>
) : showCheckmark ? (
<CheckCircle
className="w-4 h-4 text-green-400 transition-all duration-300"
aria-label="Thought complete"
/>
) : null}
<div className="flex-1 overflow-hidden">
<span
key={currentThought.content}
className="text-xs text-theme-text-secondary font-mono inline-block w-full animate-thoughtTransition"
>
{currentThought.content}
</span>
</div>
<div className="flex items-center gap-x-2">
{previousThoughts?.length > 0 && (
<div
data-tooltip-id="expand-cot"
data-tooltip-content={
isExpanded ? "Hide thought chain" : "Show thought chain"
}
className="border-none text-theme-text-secondary hover:text-theme-text-primary transition-colors p-1 rounded-full hover:bg-theme-sidebar-item-hover"
aria-label={
isExpanded ? "Hide thought chain" : "Show thought chain"
}
>
<CaretDown
className={`w-4 h-4 transform transition-transform duration-200 ${isExpanded ? "rotate-180" : ""}`}
/>
</div>
)}
</div>
</div>

{/* Previous thoughts dropdown */}
{previousThoughts?.length > 0 && (
<div className="flex justify-center w-full">
<div className="w-full max-w-[80%] flex flex-col">
<div className=" w-full max-w-[800px]">
<div
key={`cot-list-${currentThought.uuid}`}
className={`mt-2 bg-theme-bg-chat-input backdrop-blur-sm rounded-lg overflow-hidden transition-all duration-300 border border-theme-sidebar-border ${
isExpanded
? "max-h-[300px] overflow-y-auto opacity-100"
: "max-h-0 opacity-0"
}`}
onClick={handleExpandClick}
style={{ borderRadius: "6px" }}
className={`${!previousThoughts?.length ? "" : `${previousThoughts?.length ? "hover:bg-theme-sidebar-item-hover" : ""}`} items-start bg-theme-bg-chat-input py-2 px-4 flex gap-x-2`}
>
<div className="p-2">
{previousThoughts.map((thought, index) => (
<div
key={`cot-${thought.uuid || index}`}
className="flex gap-x-2"
<div className="w-7 h-7 flex justify-center flex-shrink-0 items-center">
{isThinking ? (
<video
autoPlay
loop
muted
playsInline
className="w-8 h-8 scale-150 transition-opacity duration-200 light:invert light:opacity-50"
data-tooltip-id="agent-thinking"
data-tooltip-content="Agent is thinking..."
aria-label="Agent is thinking..."
>
<p className="text-xs text-theme-text-secondary font-mono">
{index + 1}/{previousThoughts.length}
</p>
<div
className="flex items-center gap-x-3 p-2 animate-fadeUpIn"
style={{ animationDelay: `${index * 50}ms` }}
>
<span className="text-xs text-theme-text-secondary font-mono">
{thought.content}
<source src={AgentAnimation} type="video/webm" />
</video>
) : (
<img
src={AgentStatic}
alt="Agent complete"
className="w-6 h-6 transition-opacity duration-200 light:invert light:opacity-50"
data-tooltip-id="agent-thinking"
data-tooltip-content="Agent has finished thinking"
aria-label="Agent has finished thinking"
/>
)}
</div>
<div className="flex-1 min-w-0">
<div
className={`overflow-hidden transition-all duration-300 ease-in-out ${isExpanded ? "max-h-[500px]" : "max-h-6"}`}
>
<div className="text-theme-text-secondary font-mono leading-6">
{!isExpanded ? (
<span className="block w-full truncate mt-[2px]">
{currentThought.content}
</span>
</div>
</div>
))}
{/* Append current thought to the end */}
<div key={`cot-${currentThought.uuid}`} className="flex gap-x-2">
<p className="text-xs text-theme-text-secondary font-mono">
{previousThoughts.length + 1}/{previousThoughts.length + 1}
</p>
<div className="flex items-center gap-x-3 p-2 animate-fadeUpIn">
<span className="text-xs text-theme-text-secondary font-mono">
{currentThought.content}
</span>
) : (
<>
{previousThoughts.map((thought, index) => (
<div
key={`cot-${thought.uuid || index}`}
className="mb-2"
>
{thought.content}
</div>
))}
<div>{currentThought.content}</div>
</>
)}
</div>
</div>
</div>
<div className="flex items-center gap-x-2">
{previousThoughts?.length > 0 && (
<button
onClick={handleExpandClick}
data-tooltip-id="expand-cot"
data-tooltip-content={
isExpanded ? "Hide thought chain" : "Show thought chain"
}
className="border-none text-theme-text-secondary hover:text-theme-text-primary transition-colors p-1 rounded-full hover:bg-theme-sidebar-item-hover"
aria-label={
isExpanded ? "Hide thought chain" : "Show thought chain"
}
>
<CaretDown
className={`w-4 h-4 transform transition-transform duration-200 ${isExpanded ? "rotate-180" : ""}`}
/>
</button>
)}
</div>
</div>
)}
</div>
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { useState, forwardRef, useImperativeHandle } from "react";
import renderMarkdown from "@/utils/chat/markdown";
import { Brain, CaretDown } from "@phosphor-icons/react";
import { CaretDown } from "@phosphor-icons/react";
import DOMPurify from "dompurify";
import truncate from "truncate";
import { isMobile } from "react-device-detect";
import ThinkingAnimation from "@/media/animations/thinking-animation.webm";
import ThinkingStatic from "@/media/animations/thinking-static.png";

const THOUGHT_KEYWORDS = ["thought", "thinking", "think", "thought_chain"];
const CLOSING_TAGS = [...THOUGHT_KEYWORDS, "response", "answer"];
Expand Down Expand Up @@ -61,46 +62,57 @@ export const ThoughtChainComponent = forwardRef(
<div
style={{
transition: "all 0.1s ease-in-out",
borderRadius: isExpanded || autoExpand ? "6px" : "24px",
borderRadius: "6px",
}}
className={`${isExpanded || autoExpand ? "" : `${canExpand ? "hover:bg-theme-sidebar-item-hover" : ""}`} items-start bg-theme-bg-chat-input py-2 px-4 flex gap-x-2 border border-theme-sidebar-border`}
className={`${isExpanded || autoExpand ? "" : `${canExpand ? "hover:bg-theme-sidebar-item-hover" : ""}`} items-start bg-theme-bg-chat-input py-2 px-4 flex gap-x-2`}
>
{isThinking || isComplete ? (
<Brain
data-tooltip-id="cot-thinking"
data-tooltip-content={
isThinking
? "Model is thinking..."
: "Model has finished thinking"
}
className={`w-4 h-4 mt-1 ${isThinking ? "text-blue-500 animate-pulse" : "text-green-400"}`}
aria-label={
isThinking
? "Model is thinking..."
: "Model has finished thinking"
}
/>
) : null}
<div className="flex-1 overflow-hidden">
{!isExpanded && !autoExpand ? (
<span
className="text-theme-text-secondary font-mono inline-block w-full"
dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(
truncate(tagStrippedContent, THOUGHT_PREVIEW_LENGTH)
),
}}
/>
) : (
<span
className="text-theme-text-secondary font-mono inline-block w-full"
dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(
renderMarkdown(tagStrippedContent)
),
}}
/>
)}
<div
className={`w-7 h-7 flex justify-center flex-shrink-0 ${!isExpanded && !autoExpand ? "items-center" : "items-start pt-[2px]"}`}
>
{isThinking || isComplete ? (
<>
<video
autoPlay
loop
muted
playsInline
className={`w-7 h-7 transition-opacity duration-200 light:invert light:opacity-50 ${isThinking ? "opacity-100" : "opacity-0 hidden"}`}
data-tooltip-id="cot-thinking"
data-tooltip-content="Model is thinking..."
aria-label="Model is thinking..."
>
<source src={ThinkingAnimation} type="video/webm" />
</video>
<img
src={ThinkingStatic}
alt="Thinking complete"
className={`w-6 h-6 transition-opacity duration-200 light:invert light:opacity-50 ${!isThinking && isComplete ? "opacity-100" : "opacity-0 hidden"}`}
data-tooltip-id="cot-thinking"
data-tooltip-content="Model has finished thinking"
aria-label="Model has finished thinking"
/>
</>
) : null}
</div>
<div className="flex-1 min-w-0">
<div
className={`overflow-hidden transition-all transform duration-300 ease-in-out origin-top ${isExpanded || autoExpand ? "max-h-[500px]" : "max-h-6"}`}
>
<div
className={`text-theme-text-secondary font-mono leading-6 ${isExpanded || autoExpand ? "-ml-[5.5px] -mt-[4px]" : "mt-[2px]"}`}
>
<span
className={`block w-full ${!isExpanded && !autoExpand ? "truncate" : ""}`}
dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(
isExpanded || autoExpand
? renderMarkdown(tagStrippedContent)
: tagStrippedContent
),
}}
/>
</div>
</div>
</div>
<div className="flex items-center gap-x-2">
{!autoExpand && canExpand ? (
Expand All @@ -127,3 +139,4 @@ export const ThoughtChainComponent = forwardRef(
);
}
);
ThoughtChainComponent.displayName = "ThoughtChainComponent";
Binary file not shown.
Binary file added frontend/src/media/animations/agent-static.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file added frontend/src/media/animations/thinking-static.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.