mirror of
https://gitee.com/wanwujie/deer-flow
synced 2026-04-19 20:34:45 +08:00
feat: add Todos
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import type { ChatStatus } from "ai";
|
||||
import { CheckIcon, LightbulbIcon, LightbulbOffIcon } from "lucide-react";
|
||||
import { CheckIcon, LightbulbIcon, ListTodoIcon } from "lucide-react";
|
||||
import { useCallback, useMemo, useState, type ComponentProps } from "react";
|
||||
|
||||
import {
|
||||
@@ -35,6 +35,7 @@ export function InputBox({
|
||||
autoFocus,
|
||||
status = "ready",
|
||||
context,
|
||||
extraHeader,
|
||||
onContextChange,
|
||||
onSubmit,
|
||||
onStop,
|
||||
@@ -43,6 +44,7 @@ export function InputBox({
|
||||
assistantId?: string | null;
|
||||
status?: ChatStatus;
|
||||
context: Omit<AgentThreadContext, "thread_id">;
|
||||
extraHeader?: React.ReactNode;
|
||||
onContextChange?: (context: Omit<AgentThreadContext, "thread_id">) => void;
|
||||
onSubmit?: (message: PromptInputMessage) => void;
|
||||
onStop?: () => void;
|
||||
@@ -72,6 +74,12 @@ export function InputBox({
|
||||
thinking_enabled: !context.thinking_enabled,
|
||||
});
|
||||
}, [onContextChange, context]);
|
||||
const handlePlanModeToggle = useCallback(() => {
|
||||
onContextChange?.({
|
||||
...context,
|
||||
is_plan_mode: !context.is_plan_mode,
|
||||
});
|
||||
}, [onContextChange, context]);
|
||||
const handleSubmit = useCallback(
|
||||
async (message: PromptInputMessage) => {
|
||||
if (status === "streaming") {
|
||||
@@ -89,7 +97,6 @@ export function InputBox({
|
||||
<PromptInput
|
||||
className={cn(
|
||||
"bg-background/85 rounded-2xl backdrop-blur-sm transition-all duration-300 ease-out *:data-[slot='input-group']:rounded-2xl",
|
||||
"-translate-y-4 overflow-hidden",
|
||||
className,
|
||||
)}
|
||||
globalDrop
|
||||
@@ -97,6 +104,11 @@ export function InputBox({
|
||||
onSubmit={handleSubmit}
|
||||
{...props}
|
||||
>
|
||||
{extraHeader && (
|
||||
<div className="absolute top-0 right-0 left-0 z-100">
|
||||
<div className="absolute right-0 bottom-0 left-0">{extraHeader}</div>
|
||||
</div>
|
||||
)}
|
||||
<PromptInputBody>
|
||||
<PromptInputTextarea
|
||||
className={cn("size-full")}
|
||||
@@ -105,7 +117,7 @@ export function InputBox({
|
||||
/>
|
||||
</PromptInputBody>
|
||||
<PromptInputFooter className="flex">
|
||||
<div>
|
||||
<div className="flex items-center">
|
||||
<Tooltip
|
||||
content={
|
||||
context.thinking_enabled ? (
|
||||
@@ -131,7 +143,7 @@ export function InputBox({
|
||||
{context.thinking_enabled ? (
|
||||
<LightbulbIcon className="text-primary size-4" />
|
||||
) : (
|
||||
<LightbulbOffIcon className="size-4" />
|
||||
<LightbulbIcon className="size-4" />
|
||||
)}
|
||||
<span
|
||||
className={cn(
|
||||
@@ -147,6 +159,47 @@ export function InputBox({
|
||||
</PromptInputButton>
|
||||
)}
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
content={
|
||||
context.is_plan_mode ? (
|
||||
<div className="tex-sm flex flex-col gap-1">
|
||||
<div>{t.inputBox.planMode}</div>
|
||||
<div className="opacity-50">
|
||||
{t.inputBox.clickToDisablePlanMode}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="tex-sm flex flex-col gap-1">
|
||||
<div>{t.inputBox.planMode}</div>
|
||||
<div className="opacity-50">
|
||||
{t.inputBox.clickToEnablePlanMode}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
>
|
||||
{selectedModel?.supports_thinking && (
|
||||
<PromptInputButton onClick={handlePlanModeToggle}>
|
||||
<>
|
||||
{context.is_plan_mode ? (
|
||||
<ListTodoIcon className="text-primary size-4" />
|
||||
) : (
|
||||
<ListTodoIcon className="size-4" />
|
||||
)}
|
||||
<span
|
||||
className={cn(
|
||||
"text-xs font-normal",
|
||||
context.is_plan_mode
|
||||
? "text-primary"
|
||||
: "text-muted-foreground",
|
||||
)}
|
||||
>
|
||||
{t.inputBox.planMode}
|
||||
</span>
|
||||
</>
|
||||
</PromptInputButton>
|
||||
)}
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<ModelSelector
|
||||
|
||||
Reference in New Issue
Block a user