feat(canvas): add deep-thinking toggle for image mode and polish video mode icon
This commit is contained in:
parent
b5f6fd3842
commit
a1691fbd39
@ -1503,6 +1503,7 @@ export async function POST(request: Request) {
|
||||
selectedVisibilityType,
|
||||
hiddenPrompt,
|
||||
autoContext,
|
||||
deepThinkingEnabled,
|
||||
}: {
|
||||
id: string;
|
||||
message: ChatMessage;
|
||||
@ -1510,6 +1511,7 @@ export async function POST(request: Request) {
|
||||
selectedVisibilityType: VisibilityType;
|
||||
hiddenPrompt?: string;
|
||||
autoContext?: string;
|
||||
deepThinkingEnabled?: boolean;
|
||||
} = requestBody;
|
||||
|
||||
const now = Date.now();
|
||||
@ -1552,6 +1554,7 @@ export async function POST(request: Request) {
|
||||
let smartAutoHistoryImages: string[] = []; // 从历史对话中提取的图片URL(支持多张)
|
||||
let smartAutoNeedsClarification = false; // 是否需要先追问用户
|
||||
let smartAutoClarificationQuestion: string | undefined;
|
||||
const deepThinkingOn = deepThinkingEnabled !== false;
|
||||
let shouldRunAgentConversation = finalModelId === "auto";
|
||||
let shouldKeepSelectedModel = false;
|
||||
const requestedModelId = selectedChatModel;
|
||||
@ -1604,17 +1607,23 @@ export async function POST(request: Request) {
|
||||
? fixedImageProviderTypes.has(selectedModelProviderType)
|
||||
: false));
|
||||
|
||||
if (isAiModelAgentAuto(selectedModelConfig)) {
|
||||
shouldRunAgentConversation = true;
|
||||
shouldKeepSelectedModel = false;
|
||||
if (deepThinkingOn) {
|
||||
if (isAiModelAgentAuto(selectedModelConfig)) {
|
||||
shouldRunAgentConversation = true;
|
||||
shouldKeepSelectedModel = false;
|
||||
console.log(
|
||||
`[Smart Auto Mode] 🧠 Agent-only model detected, force auto routing: ${selectedModelConfig.displayName}`
|
||||
);
|
||||
} else if (isFixedVisualModel) {
|
||||
shouldRunAgentConversation = true;
|
||||
shouldKeepSelectedModel = true;
|
||||
console.log(
|
||||
`[Smart Auto Mode] 🎯 Agent conversation enabled for fixed visual model: ${selectedModelConfig.displayName} (${selectedModelProviderType || "unknown"})`
|
||||
);
|
||||
}
|
||||
} else if (isFixedVisualModel || isAiModelAgentAuto(selectedModelConfig)) {
|
||||
console.log(
|
||||
`[Smart Auto Mode] 🧠 Agent-only model detected, force auto routing: ${selectedModelConfig.displayName}`
|
||||
);
|
||||
} else if (isFixedVisualModel) {
|
||||
shouldRunAgentConversation = true;
|
||||
shouldKeepSelectedModel = true;
|
||||
console.log(
|
||||
`[Smart Auto Mode] 🎯 Agent conversation enabled for fixed visual model: ${selectedModelConfig.displayName} (${selectedModelProviderType || "unknown"})`
|
||||
`[Smart Auto Mode] ⏭️ Deep thinking disabled, skip agent analysis for: ${selectedModelConfig.displayName}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,6 +55,7 @@ export const postRequestBodySchema = z.object({
|
||||
// 支持预定义模型名称或数据库中的模型 UUID
|
||||
selectedChatModel: z.string().min(1).max(128),
|
||||
selectedVisibilityType: z.enum(["public", "private"]),
|
||||
deepThinkingEnabled: z.boolean().optional(),
|
||||
videoParams: videoParamsSchema, // 视频参数
|
||||
imageParams: imageParamsSchema, // 🆕 图片生成参数
|
||||
});
|
||||
|
||||
@ -5,7 +5,7 @@ import { DefaultChatTransport } from "ai";
|
||||
import { useEffect, useRef, useState, useCallback, useMemo } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
import useSWR from "swr";
|
||||
import { Send, Loader2, ImagePlus, Paperclip, X, User, Bot, Plus, History, LayoutGrid, Maximize2, RefreshCw, Globe, Box, ArrowUp, Video, Sparkles, Check, ChevronDown, ChevronUp, AlertCircle, CheckCircle2 } from "lucide-react";
|
||||
import { Send, Loader2, ImagePlus, Paperclip, X, User, Bot, Plus, History, LayoutGrid, Maximize2, RefreshCw, Globe, Box, ArrowUp, Video, Sparkles, Check, ChevronDown, ChevronUp, AlertCircle, CheckCircle2, Brain } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||
@ -808,8 +808,10 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
|
||||
const [videoSlotUploading, setVideoSlotUploading] = useState<number | null>(null);
|
||||
const [lastImageModelId, setLastImageModelId] = useState<string | null>(null);
|
||||
const [lastVideoModelId, setLastVideoModelId] = useState<string | null>(null);
|
||||
const [deepThinkingEnabled, setDeepThinkingEnabled] = useState(true);
|
||||
const imageParamsRef = useRef(imageParams);
|
||||
const videoParamsRef = useRef(videoParams);
|
||||
const deepThinkingEnabledRef = useRef(deepThinkingEnabled);
|
||||
|
||||
// 🆕 保存图片参数到 localStorage
|
||||
const handleImageParamsChange = (params: ImageGenerationParams) => {
|
||||
@ -1614,6 +1616,10 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
|
||||
videoParamsRef.current = videoParams;
|
||||
}, [videoParams]);
|
||||
|
||||
useEffect(() => {
|
||||
deepThinkingEnabledRef.current = deepThinkingEnabled;
|
||||
}, [deepThinkingEnabled]);
|
||||
|
||||
useEffect(() => {
|
||||
isVideoModelRef.current = isVideoModel;
|
||||
}, [isVideoModel]);
|
||||
@ -1898,6 +1904,10 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
|
||||
message: request.messages.at(-1),
|
||||
selectedChatModel: currentModelIdRef.current,
|
||||
selectedVisibilityType: "private",
|
||||
deepThinkingEnabled:
|
||||
isVideoModelRef.current || currentModelIdRef.current === "auto"
|
||||
? undefined
|
||||
: deepThinkingEnabledRef.current,
|
||||
videoParams: isVideoModelRef.current ? videoParamsRef.current || undefined : undefined,
|
||||
imageParams: isVideoModelRef.current ? undefined : imageParamsRef.current || undefined,
|
||||
hiddenPrompt,
|
||||
@ -5400,6 +5410,24 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2 flex-shrink-0">
|
||||
{activeComposerMode === "image" ? (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
title={`深度思考:${deepThinkingEnabled ? "开" : "关"}`}
|
||||
className={cn(
|
||||
"h-8 w-8 rounded-full border transition-colors",
|
||||
deepThinkingEnabled
|
||||
? "border-[#8ab0ff] bg-[#eef4ff] text-[#3b5bcc] hover:bg-[#e5efff]"
|
||||
: "border-[#d8dce3] bg-white text-[#6b7280] hover:bg-[#f4f6f8]"
|
||||
)}
|
||||
onClick={() => setDeepThinkingEnabled((prev) => !prev)}
|
||||
disabled={isSubmitting}
|
||||
>
|
||||
<Brain className="h-4 w-4" />
|
||||
</Button>
|
||||
) : null}
|
||||
|
||||
{activeComposerMode !== "agent" ? (
|
||||
<Select
|
||||
value={modelSelectValue}
|
||||
|
||||
@ -29,7 +29,7 @@ import {
|
||||
Camera,
|
||||
Clock,
|
||||
Settings2,
|
||||
Maximize2,
|
||||
Clapperboard,
|
||||
Monitor,
|
||||
Ratio,
|
||||
} from "lucide-react";
|
||||
@ -277,7 +277,7 @@ const getImageUploadConfig = () => {
|
||||
className="h-8 px-2 focus-visible:ring-0 focus-visible:ring-offset-0"
|
||||
title={`模式:${modeOptions.find((option) => option.value === params.mode)?.label || MODE_LABELS[params.mode]}`}
|
||||
>
|
||||
<Maximize2 size={14} />
|
||||
<Clapperboard size={14} />
|
||||
<span className="sr-only">
|
||||
{`模式:${modeOptions.find((option) => option.value === params.mode)?.label || MODE_LABELS[params.mode]}`}
|
||||
</span>
|
||||
@ -563,7 +563,7 @@ const getImageUploadConfig = () => {
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" size="sm" className="gap-1 px-2 h-8 focus-visible:ring-0 focus-visible:ring-offset-0">
|
||||
<Maximize2 size={14} />
|
||||
<Clapperboard size={14} />
|
||||
{modeOptions.find((option) => option.value === params.mode)?.label || MODE_LABELS[params.mode]}
|
||||
<ChevronDown size={12} className="opacity-50" />
|
||||
</Button>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user