feat: enable edit context options

This commit is contained in:
Henry Li
2026-01-16 09:37:04 +08:00
parent 956f8f0cfb
commit 3f2bfded41
2 changed files with 113 additions and 5 deletions

View File

@@ -114,6 +114,8 @@ export default function ChatPage() {
className="max-w-(--container-width-md)"
autoFocus={isNewThread}
status={thread.isLoading ? "streaming" : "ready"}
context={threadContext}
onContextChange={setThreadContext}
onSubmit={handleSubmit}
onStop={handleStop}
/>

View File

@@ -1,6 +1,6 @@
import type { ChatStatus } from "ai";
import { LightbulbIcon, LightbulbOffIcon } from "lucide-react";
import { useCallback, type ComponentProps } from "react";
import { CheckIcon, LightbulbIcon, LightbulbOffIcon } from "lucide-react";
import { useCallback, useMemo, useState, type ComponentProps } from "react";
import {
PromptInput,
@@ -11,23 +11,70 @@ import {
PromptInputTextarea,
type PromptInputMessage,
} from "@/components/ai-elements/prompt-input";
import type { AgentThreadContext } from "@/core/threads";
import { cn } from "@/lib/utils";
import {
ModelSelector,
ModelSelectorContent,
ModelSelectorInput,
ModelSelectorItem,
ModelSelectorList,
ModelSelectorLogo,
ModelSelectorName,
ModelSelectorTrigger,
type ModelSelectorLogoProps,
} from "../ai-elements/model-selector";
import { Tooltip } from "./tooltip";
const AVAILABLE_MODELS = [
{ name: "deepseek-v3.2", displayName: "DeepSeek v3.2", provider: "deepseek" },
{
name: "doubao-seed-1.8",
displayName: "Doubao Seed 1.8",
provider: "doubao",
},
];
export function InputBox({
className,
autoFocus,
status = "ready",
context,
onContextChange,
onSubmit,
onStop,
...props
}: Omit<ComponentProps<typeof PromptInput>, "onSubmit"> & {
assistantId?: string | null;
status?: ChatStatus;
context: AgentThreadContext;
onContextChange?: (context: AgentThreadContext) => void;
onSubmit?: (message: PromptInputMessage) => void;
onStop?: () => void;
}) {
const [modelDialogOpen, setModelDialogOpen] = useState(false);
const selectedModel = useMemo(
() => AVAILABLE_MODELS.find((m) => m.name === context.model),
[context.model],
);
const handleModelSelect = useCallback(
(model: string) => {
onContextChange?.({
...context,
model,
});
setModelDialogOpen(false);
},
[onContextChange, context],
);
const handleThinkingToggle = useCallback(() => {
onContextChange?.({
...context,
thinking_enabled: !context.thinking_enabled,
});
}, [onContextChange, context]);
const handleSubmit = useCallback(
async (message: PromptInputMessage) => {
if (status === "streaming") {
@@ -62,13 +109,72 @@ export function InputBox({
</PromptInputBody>
<PromptInputFooter className="flex">
<div>
<Tooltip content="">
<PromptInputButton>
<LightbulbOffIcon className="size-4" />
<Tooltip
content={
context.thinking_enabled ? (
<div className="tex-sm flex flex-col gap-1">
<div>Thinking is enabled</div>
<div className="opacity-50">Click to disable thinking</div>
</div>
) : (
<div className="tex-sm flex flex-col gap-1">
<div>Thinking is disabled</div>
<div className="opacity-50">Click to enable thinking</div>
</div>
)
}
>
<PromptInputButton onClick={handleThinkingToggle}>
{context.thinking_enabled ? (
<LightbulbIcon className="text-primary size-4" />
) : (
<LightbulbOffIcon className="size-4" />
)}
</PromptInputButton>
</Tooltip>
</div>
<div className="flex items-center gap-2">
<ModelSelector
open={modelDialogOpen}
onOpenChange={setModelDialogOpen}
>
<ModelSelectorTrigger asChild>
<PromptInputButton>
<ModelSelectorLogo
className="size-4"
provider={
selectedModel?.provider as ModelSelectorLogoProps["provider"]
}
/>
<ModelSelectorName>
{selectedModel?.displayName}
</ModelSelectorName>
</PromptInputButton>
</ModelSelectorTrigger>
<ModelSelectorContent>
<ModelSelectorInput placeholder="Search models..." />
<ModelSelectorList>
{AVAILABLE_MODELS.map((m) => (
<ModelSelectorItem
key={m.name}
value={m.name}
onSelect={() => handleModelSelect(m.name)}
>
<ModelSelectorLogo
className="size-4"
provider={m.provider}
/>
<ModelSelectorName>{m.displayName}</ModelSelectorName>
{m.name === context.model ? (
<CheckIcon className="ml-auto size-4" />
) : (
<div className="ml-auto size-4" />
)}
</ModelSelectorItem>
))}
</ModelSelectorList>
</ModelSelectorContent>
</ModelSelector>
<PromptInputSubmit
className="rounded-full"
variant="outline"