style: refine model badge typography to match competitor
This commit is contained in:
parent
8cd3fa2954
commit
ba10d4e5be
@ -5,7 +5,7 @@ import { DefaultChatTransport } from "ai";
|
||||
import { useEffect, useRef, useState, useCallback, useMemo } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
import useSWR, { useSWRConfig } from "swr";
|
||||
import { Send, Loader2, ImagePlus, Paperclip, X, Plus, History, LayoutGrid, Maximize2, RefreshCw, Globe, Box, ArrowUp, Video, Sparkles, Check, ChevronDown, ChevronUp, AlertCircle, CheckCircle2, Brain, ThumbsUp, ThumbsDown } from "lucide-react";
|
||||
import { Send, Loader2, ImagePlus, Paperclip, X, Plus, History, LayoutGrid, Maximize2, RefreshCw, Globe, Box, ArrowUp, Video, Sparkles, Check, ChevronDown, ChevronUp, AlertCircle, CheckCircle2, Brain, ThumbsUp, ThumbsDown, Eye } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import {
|
||||
@ -5492,8 +5492,9 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
|
||||
</div>
|
||||
<div className="mt-1 flex items-center gap-2 text-[#8f96a3]">
|
||||
{showModelMeta ? (
|
||||
<span className="text-[12px] font-medium tracking-tight text-[#8d94a2]">
|
||||
◈ {assistantModelName}
|
||||
<span className="inline-flex items-center gap-1.5 text-[11px] font-medium tracking-tight text-[#a2a9b5]">
|
||||
<Eye className="h-3.5 w-3.5 opacity-80" />
|
||||
<span>{assistantModelName}</span>
|
||||
</span>
|
||||
) : null}
|
||||
{showVoteActions ? (
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
import type { UseChatHelpers } from "@ai-sdk/react";
|
||||
import equal from "fast-deep-equal";
|
||||
import { Eye } from "lucide-react";
|
||||
import { memo, useState } from "react";
|
||||
import type { Vote } from "@/lib/db/schema";
|
||||
import type { ChatMessage } from "@/lib/types";
|
||||
@ -174,18 +175,22 @@ function filterAgentRoutingNoise(text: string): string {
|
||||
}
|
||||
|
||||
const IMAGE_DONE_SUMMARY = "已完成本次生成,如需微调可继续告诉我。";
|
||||
const MODEL_BADGE_REGEX =
|
||||
/^\s*[◈◇◆🔹⬡✦•·]\s*[A-Za-z][A-Za-z0-9 .:+\-_/()]{2,}\s*$/im;
|
||||
const MODEL_BADGE_LINE_REGEX =
|
||||
/^\s*[◈◇◆🔹⬡✦•·]\s*([A-Za-z][A-Za-z0-9 .:+\-_/()]{2,})\s*$/im;
|
||||
const MODEL_BADGE_LINE_GLOBAL_REGEX =
|
||||
/^\s*[◈◇◆🔹⬡✦•·]\s*[A-Za-z][A-Za-z0-9 .:+\-_/()]{2,}\s*$/gim;
|
||||
|
||||
function ensureImageModelBadge(text: string, fallbackModelName?: string): string {
|
||||
if (!text) return text;
|
||||
const normalized = String(text || "").trim();
|
||||
if (!normalized) return normalized;
|
||||
const modelName = String(fallbackModelName || "").trim();
|
||||
if (!modelName) return normalized;
|
||||
if (!/!\[[^\]]*\]\((https?:\/\/[^\s)]+)\)/i.test(normalized)) return normalized;
|
||||
if (MODEL_BADGE_REGEX.test(normalized)) return normalized;
|
||||
return `◈ ${modelName}\n\n${normalized}`;
|
||||
function extractModelBadgeName(text: string): string {
|
||||
if (!text) return "";
|
||||
const match = String(text || "").match(MODEL_BADGE_LINE_REGEX);
|
||||
return match?.[1]?.trim() || "";
|
||||
}
|
||||
|
||||
function stripModelBadgeLines(text: string): string {
|
||||
return String(text || "")
|
||||
.replace(MODEL_BADGE_LINE_GLOBAL_REGEX, "")
|
||||
.replace(/\n{3,}/g, "\n\n")
|
||||
.trim();
|
||||
}
|
||||
|
||||
function appendImageDoneSummary(text: string): string {
|
||||
@ -342,19 +347,39 @@ const PurePreviewMessage = ({
|
||||
}
|
||||
|
||||
// 应用视频内容过滤
|
||||
const routedFilteredText =
|
||||
message.role === "assistant"
|
||||
? filterAgentRoutingNoise(filterVideoContent(part.text))
|
||||
: part.text;
|
||||
const extractedModelName =
|
||||
message.role === "assistant"
|
||||
? extractModelBadgeName(routedFilteredText)
|
||||
: "";
|
||||
const contentWithoutBadge =
|
||||
message.role === "assistant"
|
||||
? stripModelBadgeLines(routedFilteredText)
|
||||
: routedFilteredText;
|
||||
const inferredFallbackModelName =
|
||||
message.role === "assistant" &&
|
||||
!extractedModelName &&
|
||||
extractImageUrlsFromText(contentWithoutBadge).length > 0
|
||||
? String(fallbackImageModelName || "").trim()
|
||||
: "";
|
||||
const displayModelName = extractedModelName || inferredFallbackModelName;
|
||||
const filteredText =
|
||||
message.role === "assistant"
|
||||
? appendImageDoneSummary(
|
||||
ensureImageModelBadge(
|
||||
filterAgentRoutingNoise(filterVideoContent(part.text)),
|
||||
fallbackImageModelName
|
||||
)
|
||||
)
|
||||
: part.text;
|
||||
? appendImageDoneSummary(contentWithoutBadge)
|
||||
: contentWithoutBadge;
|
||||
const textParts = parseAnnotations(filteredText);
|
||||
|
||||
return (
|
||||
<div key={key}>
|
||||
{message.role === "assistant" && displayModelName ? (
|
||||
<div className="mb-2 inline-flex items-center gap-1.5 text-[12px] font-medium leading-none text-[#a2a9b5]">
|
||||
<Eye className="h-3.5 w-3.5 opacity-80" />
|
||||
<span className="tracking-tight">{displayModelName}</span>
|
||||
</div>
|
||||
) : null}
|
||||
<MessageContent
|
||||
className={cn({
|
||||
"w-fit break-words rounded-2xl px-3 py-2 text-right text-white":
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user