feat: use "mode" instead of "thinking_enabled" and "is_plan_mode"

This commit is contained in:
Henry Li
2026-01-29 15:48:50 +08:00
parent 4411af68f5
commit 62ac3b6b03
4 changed files with 46 additions and 49 deletions

View File

@@ -108,7 +108,11 @@ export default function ChatPage() {
isNewThread, isNewThread,
threadId, threadId,
thread, thread,
threadContext: settings.context, threadContext: {
...settings.context,
thinking_enabled: settings.context.mode !== "flash",
is_plan_mode: settings.context.mode === "pro",
},
afterSubmit() { afterSubmit() {
router.push(pathOfThread(threadId!)); router.push(pathOfThread(threadId!));
}, },

View File

@@ -5,7 +5,6 @@ import { useCallback, useEffect, useState } from "react";
import { Toaster } from "sonner"; import { Toaster } from "sonner";
import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar"; import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar";
import { Overscroll } from "@/components/workspace/overscroll";
import { WorkspaceSidebar } from "@/components/workspace/workspace-sidebar"; import { WorkspaceSidebar } from "@/components/workspace/workspace-sidebar";
import { useLocalSettings } from "@/core/settings"; import { useLocalSettings } from "@/core/settings";

View File

@@ -62,10 +62,22 @@ export function InputBox({
assistantId?: string | null; assistantId?: string | null;
status?: ChatStatus; status?: ChatStatus;
disabled?: boolean; disabled?: boolean;
context: Omit<AgentThreadContext, "thread_id">; context: Omit<
AgentThreadContext,
"thread_id" | "is_plan_mode" | "thinking_enabled"
> & {
mode: "flash" | "thinking" | "pro" | undefined;
};
extraHeader?: React.ReactNode; extraHeader?: React.ReactNode;
isNewThread?: boolean; isNewThread?: boolean;
onContextChange?: (context: Omit<AgentThreadContext, "thread_id">) => void; onContextChange?: (
context: Omit<
AgentThreadContext,
"thread_id" | "is_plan_mode" | "thinking_enabled"
> & {
mode: "flash" | "thinking" | "pro" | undefined;
},
) => void;
onSubmit?: (message: PromptInputMessage) => void; onSubmit?: (message: PromptInputMessage) => void;
onStop?: () => void; onStop?: () => void;
}) { }) {
@@ -74,13 +86,15 @@ export function InputBox({
const { models } = useModels(); const { models } = useModels();
const selectedModel = useMemo(() => { const selectedModel = useMemo(() => {
if (!context.model_name && models.length > 0) { if (!context.model_name && models.length > 0) {
const model = models[0]!;
setTimeout(() => { setTimeout(() => {
onContextChange?.({ onContextChange?.({
...context, ...context,
model_name: models[0]!.name, model_name: model.name,
mode: model.supports_thinking ? "pro" : "flash",
}); });
}, 0); }, 0);
return models[0]!; return model;
} }
return models.find((m) => m.name === context.model_name); return models.find((m) => m.name === context.model_name);
}, [context, models, onContextChange]); }, [context, models, onContextChange]);
@@ -88,48 +102,22 @@ export function InputBox({
() => selectedModel?.supports_thinking ?? false, () => selectedModel?.supports_thinking ?? false,
[selectedModel], [selectedModel],
); );
const mode = useMemo(() => {
if (context.is_plan_mode) {
return "pro";
}
if (context.thinking_enabled) {
return "thinking";
}
return "flash";
}, [context.thinking_enabled, context.is_plan_mode]);
const handleModelSelect = useCallback( const handleModelSelect = useCallback(
(model_name: string) => { (model_name: string) => {
const supports_thinking = selectedModel?.supports_thinking ?? false;
onContextChange?.({ onContextChange?.({
...context, ...context,
model_name, model_name,
thinking_enabled: supports_thinking && context.thinking_enabled,
}); });
setModelDialogOpen(false); setModelDialogOpen(false);
}, },
[selectedModel?.supports_thinking, onContextChange, context], [onContextChange, context],
); );
const handleModeSelect = useCallback( const handleModeSelect = useCallback(
(mode: "flash" | "thinking" | "pro") => { (mode: "flash" | "thinking" | "pro") => {
if (mode === "flash") {
onContextChange?.({ onContextChange?.({
...context, ...context,
thinking_enabled: false, mode,
is_plan_mode: false,
}); });
} else if (mode === "thinking") {
onContextChange?.({
...context,
thinking_enabled: true,
is_plan_mode: false,
});
} else if (mode === "pro") {
onContextChange?.({
...context,
thinking_enabled: true,
is_plan_mode: true,
});
}
}, },
[onContextChange, context], [onContextChange, context],
); );
@@ -192,7 +180,7 @@ export function InputBox({
<PromptInputActionMenu> <PromptInputActionMenu>
<PromptInputActionMenuItem <PromptInputActionMenuItem
className={cn( className={cn(
mode === "flash" context.mode === "flash"
? "text-accent-foreground" ? "text-accent-foreground"
: "text-muted-foreground/65", : "text-muted-foreground/65",
)} )}
@@ -203,7 +191,8 @@ export function InputBox({
<ZapIcon <ZapIcon
className={cn( className={cn(
"mr-2 size-4", "mr-2 size-4",
mode === "flash" && "text-accent-foreground", context.mode === "flash" &&
"text-accent-foreground",
)} )}
/> />
{t.inputBox.flashMode} {t.inputBox.flashMode}
@@ -212,7 +201,7 @@ export function InputBox({
{t.inputBox.flashModeDescription} {t.inputBox.flashModeDescription}
</div> </div>
</div> </div>
{mode === "flash" ? ( {context.mode === "flash" ? (
<CheckIcon className="ml-auto size-4" /> <CheckIcon className="ml-auto size-4" />
) : ( ) : (
<div className="ml-auto size-4" /> <div className="ml-auto size-4" />
@@ -221,7 +210,7 @@ export function InputBox({
{supportThinking && ( {supportThinking && (
<PromptInputActionMenuItem <PromptInputActionMenuItem
className={cn( className={cn(
mode === "thinking" context.mode === "thinking"
? "text-accent-foreground" ? "text-accent-foreground"
: "text-muted-foreground/65", : "text-muted-foreground/65",
)} )}
@@ -232,7 +221,8 @@ export function InputBox({
<LightbulbIcon <LightbulbIcon
className={cn( className={cn(
"mr-2 size-4", "mr-2 size-4",
mode === "thinking" && "text-accent-foreground", context.mode === "thinking" &&
"text-accent-foreground",
)} )}
/> />
{t.inputBox.reasoningMode} {t.inputBox.reasoningMode}
@@ -241,7 +231,7 @@ export function InputBox({
{t.inputBox.reasoningModeDescription} {t.inputBox.reasoningModeDescription}
</div> </div>
</div> </div>
{mode === "thinking" ? ( {context.mode === "thinking" ? (
<CheckIcon className="ml-auto size-4" /> <CheckIcon className="ml-auto size-4" />
) : ( ) : (
<div className="ml-auto size-4" /> <div className="ml-auto size-4" />
@@ -250,7 +240,7 @@ export function InputBox({
)} )}
<PromptInputActionMenuItem <PromptInputActionMenuItem
className={cn( className={cn(
mode === "pro" context.mode === "pro"
? "text-accent-foreground" ? "text-accent-foreground"
: "text-muted-foreground/65", : "text-muted-foreground/65",
)} )}
@@ -261,7 +251,7 @@ export function InputBox({
<GraduationCapIcon <GraduationCapIcon
className={cn( className={cn(
"mr-2 size-4", "mr-2 size-4",
mode === "pro" && "text-accent-foreground", context.mode === "pro" && "text-accent-foreground",
)} )}
/> />
{t.inputBox.proMode} {t.inputBox.proMode}
@@ -270,7 +260,7 @@ export function InputBox({
{t.inputBox.proModeDescription} {t.inputBox.proModeDescription}
</div> </div>
</div> </div>
{mode === "pro" ? ( {context.mode === "pro" ? (
<CheckIcon className="ml-auto size-4" /> <CheckIcon className="ml-auto size-4" />
) : ( ) : (
<div className="ml-auto size-4" /> <div className="ml-auto size-4" />

View File

@@ -3,8 +3,7 @@ import type { AgentThreadContext } from "../threads";
export const DEFAULT_LOCAL_SETTINGS: LocalSettings = { export const DEFAULT_LOCAL_SETTINGS: LocalSettings = {
context: { context: {
model_name: undefined, model_name: undefined,
thinking_enabled: true, mode: undefined,
is_plan_mode: true,
}, },
layout: { layout: {
sidebar_collapsed: false, sidebar_collapsed: false,
@@ -14,7 +13,12 @@ export const DEFAULT_LOCAL_SETTINGS: LocalSettings = {
const LOCAL_SETTINGS_KEY = "deerflow.local-settings"; const LOCAL_SETTINGS_KEY = "deerflow.local-settings";
export interface LocalSettings { export interface LocalSettings {
context: Omit<AgentThreadContext, "thread_id">; context: Omit<
AgentThreadContext,
"thread_id" | "is_plan_mode" | "thinking_enabled"
> & {
mode: "flash" | "thinking" | "pro" | undefined;
};
layout: { layout: {
sidebar_collapsed: boolean; sidebar_collapsed: boolean;
}; };