refactor: use dropdown for vision prompt mode

This commit is contained in:
Xin Wang
2026-08-12 21:38:42 +08:00
parent 94a02d7e2b
commit 7c18cea16d
3 changed files with 41 additions and 59 deletions
@@ -1,6 +1,6 @@
"use client"; "use client";
import { Camera, Check } from "lucide-react"; import { Camera } from "lucide-react";
import { import {
ResourceSelectField, ResourceSelectField,
@@ -20,16 +20,16 @@ const promptModes: Array<{
title: string; title: string;
description: string; description: string;
}> = [ }> = [
{
value: "runtime",
title: "运行时自动生成(默认)",
description: "模型结合当前对话,临时生成看图问题。",
},
{ {
value: "fixed", value: "fixed",
title: "固定提示词", title: "固定提示词",
description: "每次获取画面都发送同一个问题。", description: "每次获取画面都发送同一个问题。",
}, },
{
value: "runtime",
title: "运行时自动生成",
description: "模型结合当前对话,临时生成看图问题。",
},
{ {
value: "guided", value: "guided",
title: "固定提示词引导", title: "固定提示词引导",
@@ -72,6 +72,10 @@ export function VisionConfigSection({
const independentModelOptions = modelOptions.filter( const independentModelOptions = modelOptions.filter(
(option) => option.value !== mainModelResourceId, (option) => option.value !== mainModelResourceId,
); );
const effectivePromptMode = promptMode || "runtime";
const selectedPromptMode =
promptModes.find((option) => option.value === effectivePromptMode) ??
promptModes[0];
return ( return (
<SectionCard <SectionCard
@@ -99,54 +103,32 @@ export function VisionConfigSection({
当前模型未标记支持图片输入,请选择独立视觉模型。 当前模型未标记支持图片输入,请选择独立视觉模型。
</p> </p>
)} )}
<div className="space-y-2"> <div className="space-y-1.5">
<label className="text-sm font-medium text-foreground"> <ResourceSelectField
看图问题生成方式 label="看图问题生成方式"
</label> value={effectivePromptMode}
<div role="radiogroup" aria-label="看图问题生成方式" className="space-y-2"> options={promptModes.map((option) => ({
{promptModes.map((option) => { value: option.value,
const selected = promptMode === option.value; label: option.title,
return ( }))}
<button onChange={(value) =>
key={option.value} onPromptModeChange(
type="button" value === "fixed" || value === "guided"
role="radio" ? value
aria-checked={selected} : "runtime",
onClick={() => onPromptModeChange(option.value)} )
className={[ }
"flex w-full items-start gap-3 rounded-xl border px-3.5 py-3 text-left transition-colors", />
selected <p className="text-[11px] leading-5 text-muted-soft">
? "border-primary bg-surface-strong/70 ring-1 ring-primary" {selectedPromptMode.description}
: "border-hairline bg-background hover:border-hairline-strong", </p>
].join(" ")}
>
<span
className={[
"mt-0.5 flex h-5 w-5 shrink-0 items-center justify-center rounded-full border",
selected
? "border-primary bg-primary text-primary-foreground"
: "border-hairline-strong text-transparent",
].join(" ")}
>
<Check size={12} />
</span>
<span className="min-w-0">
<span className="block text-sm font-medium text-foreground">
{option.title}
</span>
<span className="mt-0.5 block text-xs leading-5 text-muted-foreground">
{option.description}
</span>
</span>
</button>
);
})}
</div> </div>
</div> {effectivePromptMode !== "runtime" && (
{promptMode !== "runtime" && (
<div className="space-y-1.5"> <div className="space-y-1.5">
<label className="text-sm font-medium text-foreground"> <label className="text-sm font-medium text-foreground">
{promptMode === "fixed" ? "固定视觉提示词" : "运行时提示词引导"} {effectivePromptMode === "fixed"
? "固定视觉提示词"
: "运行时提示词引导"}
</label> </label>
<Textarea <Textarea
value={prompt} value={prompt}
@@ -154,14 +136,14 @@ export function VisionConfigSection({
rows={5} rows={5}
onChange={(event) => onPromptChange(event.target.value)} onChange={(event) => onPromptChange(event.target.value)}
placeholder={ placeholder={
promptMode === "fixed" effectivePromptMode === "fixed"
? "例如:请识别画面中的车辆数量、碰撞位置、明显损伤和人员状态。" ? "例如:请识别画面中的车辆数量、碰撞位置、明显损伤和人员状态。"
: "例如:问题应聚焦车辆数量、碰撞位置和人员状态;只询问画面中可直接判断的信息。" : "例如:问题应聚焦车辆数量、碰撞位置和人员状态;只询问画面中可直接判断的信息。"
} }
className="field-sizing-fixed min-h-28 resize-y border-hairline-strong bg-background text-sm leading-6 text-foreground placeholder:text-muted-soft" className="field-sizing-fixed min-h-28 resize-y border-hairline-strong bg-background text-sm leading-6 text-foreground placeholder:text-muted-soft"
/> />
<p className="text-[11px] leading-5 text-muted-soft"> <p className="text-[11px] leading-5 text-muted-soft">
{promptMode === "fixed" {effectivePromptMode === "fixed"
? "工具调用时不会让模型改写这段内容。" ? "工具调用时不会让模型改写这段内容。"
: "模型会结合当前对话生成具体问题,并受到这段内容约束。"} : "模型会结合当前对话生成具体问题,并受到这段内容约束。"}
</p> </p>
@@ -15,8 +15,8 @@ export function settingsFromWorkflowGraph(
tts: graph.settings.defaultTtsResourceId, tts: graph.settings.defaultTtsResourceId,
visionEnabled: graph.settings.visionEnabled, visionEnabled: graph.settings.visionEnabled,
visionModelResourceId: graph.settings.visionModelResourceId, visionModelResourceId: graph.settings.visionModelResourceId,
visionPromptMode: graph.settings.visionPromptMode, visionPromptMode: graph.settings.visionPromptMode ?? "runtime",
visionPrompt: graph.settings.visionPrompt, visionPrompt: graph.settings.visionPrompt ?? "",
toolIds: graph.settings.toolIds, toolIds: graph.settings.toolIds,
knowledgeBaseId: graph.settings.knowledgeBaseId, knowledgeBaseId: graph.settings.knowledgeBaseId,
knowledgeRetrievalConfig: { knowledgeRetrievalConfig: {
@@ -46,8 +46,8 @@ export function workflowGraphWithSettings(
defaultTtsResourceId: settings.tts ?? "", defaultTtsResourceId: settings.tts ?? "",
visionEnabled: settings.visionEnabled, visionEnabled: settings.visionEnabled,
visionModelResourceId: settings.visionModelResourceId, visionModelResourceId: settings.visionModelResourceId,
visionPromptMode: settings.visionPromptMode, visionPromptMode: settings.visionPromptMode ?? "runtime",
visionPrompt: settings.visionPrompt, visionPrompt: settings.visionPrompt ?? "",
toolIds: settings.toolIds, toolIds: settings.toolIds,
knowledgeBaseId: settings.knowledgeBaseId, knowledgeBaseId: settings.knowledgeBaseId,
knowledgeMode: settings.knowledgeRetrievalConfig.mode, knowledgeMode: settings.knowledgeRetrievalConfig.mode,
@@ -184,8 +184,8 @@ export function GlobalSettingsPanel({
} }
enabled={settings.visionEnabled} enabled={settings.visionEnabled}
modelResourceId={settings.visionModelResourceId} modelResourceId={settings.visionModelResourceId}
promptMode={settings.visionPromptMode} promptMode={settings.visionPromptMode ?? "runtime"}
prompt={settings.visionPrompt} prompt={settings.visionPrompt ?? ""}
mainModelResourceId={ mainModelResourceId={
settings.runtimeMode === "realtime" settings.runtimeMode === "realtime"
? settings.realtime ?? "" ? settings.realtime ?? ""