feat: organize tools and enable qwen realtime calls

This commit is contained in:
Xin Wang
2026-08-14 00:15:00 +08:00
parent eb111a3890
commit 5be21f5ccc
71 changed files with 5771 additions and 2026 deletions
@@ -33,12 +33,13 @@ import {
ResourceSelectField,
RuntimeModeSelector,
TextAreaField,
ToolPicker,
} from "@/components/assistant-editor/editor-controls";
import type { AssistantForm } from "@/components/assistant-editor/types";
import { SectionAnchorTabs } from "@/components/editor/section-anchor-tabs";
import { SectionCard } from "@/components/editor/section-card";
import { VisionConfigSection } from "@/components/editor/vision-config-section";
import { BuiltInToolsEditor } from "@/components/assistant-editor/built-in-tools";
import { ToolBindingEditor } from "@/components/tools/tool-binding-editor";
import { TurnConfigEditor } from "@/components/turn-config-editor";
import { Button } from "@/components/ui/button";
import {
@@ -56,7 +57,13 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import type { DynamicVariableDefinition, StartupConfig, Tool } from "@/lib/api";
import type {
BuiltInTools,
DynamicVariableDefinition,
RealtimePromptToolFeatures,
StartupConfig,
Tool,
} from "@/lib/api";
type ResourceOption = { value: string; label: string };
type PromptOpeningMode = StartupConfig["openingMode"];
@@ -117,6 +124,7 @@ type PromptEditorProps = {
visionModelOptions: ResourceOption[];
knowledgeOptions: ResourceOption[];
tools: Tool[];
realtimeToolFeatures?: RealtimePromptToolFeatures;
onBack: () => void;
onSave: () => void;
onDelete?: () => void | Promise<void>;
@@ -142,6 +150,7 @@ export function PromptEditor({
visionModelOptions,
knowledgeOptions: kbOptions,
tools,
realtimeToolFeatures,
onBack,
onSave,
onDelete,
@@ -587,16 +596,6 @@ export function PromptEditor({
openingMessage: null,
});
}
if (runtimeMode === "realtime") {
updateForm(
"toolIds",
form.toolIds.filter(
(id) =>
tools.find((tool) => tool.id === id)?.type !==
"system",
),
);
}
}}
/>
@@ -692,20 +691,121 @@ export function PromptEditor({
</SectionCard>
)}
{(form.runtimeMode === "pipeline" ||
Boolean(realtimeToolFeatures)) && (
<SectionCard
icon={<Sparkles size={15} />}
title="内建能力"
description="配置平台提供的结束、状态更新与人工接管能力"
>
<BuiltInToolsEditor
value={form.builtInTools}
variables={dynamicVariableDefinitions}
allowedKeys={
form.runtimeMode === "realtime"
? realtimeToolFeatures?.builtIns
: undefined
}
onChange={(builtInTools) =>
updateForm("builtInTools", builtInTools)
}
/>
</SectionCard>
)}
{form.runtimeMode === "realtime" && !realtimeToolFeatures && (
<SectionCard
icon={<Sparkles size={15} />}
title="Realtime 工具"
description="当前 Realtime 接口尚未开放 Prompt 工具调用"
>
<p className="text-sm text-muted-foreground">
已有配置会被保留,但保存前需要切换到支持工具的模型或清理这些配置。
</p>
</SectionCard>
)}
{form.runtimeMode === "realtime" && (() => {
const allowedBuiltIns = new Set(
realtimeToolFeatures?.builtIns ?? [],
);
const unsupportedBuiltIns = (
Object.keys(form.builtInTools) as Array<keyof BuiltInTools>
).filter(
(key) =>
Boolean(form.builtInTools[key]) &&
!allowedBuiltIns.has(key),
);
const allowedExternal = new Set(
realtimeToolFeatures?.externalTypes ?? [],
);
const unsupportedToolIds = new Set(
form.toolBindings
.filter((binding) => {
const tool = tools.find((item) => item.id === binding.toolId);
return !tool || !allowedExternal.has(tool.type);
})
.map((binding) => binding.toolId),
);
if (!unsupportedBuiltIns.length && !unsupportedToolIds.size) {
return null;
}
return (
<SectionCard
icon={<Wrench size={15} />}
title="存在不兼容工具配置"
description="这些配置不会被自动删除,后端也会阻止保存"
>
<div className="flex items-center justify-between gap-3">
<p className="text-sm text-muted-foreground">
{unsupportedBuiltIns.length} 个内建工具,
{unsupportedToolIds.size} 个外部工具不受当前接口支持。
</p>
<Button
type="button"
variant="outline"
onClick={() => {
updateForm(
"builtInTools",
Object.fromEntries(
Object.entries(form.builtInTools).filter(([key]) =>
allowedBuiltIns.has(key as keyof BuiltInTools),
),
) as BuiltInTools,
);
updateForm(
"toolBindings",
form.toolBindings.filter(
(binding) => !unsupportedToolIds.has(binding.toolId),
),
);
}}
>
清理不兼容配置
</Button>
</div>
</SectionCard>
);
})()}
<SectionCard
icon={<Wrench size={15} />}
title="工具"
description="配置该提示词助手可以调用的工具"
title="外部工具"
description="选择可复用资源,并配置当前助手的参数来源与结果映射"
>
<ToolPicker
tools={tools.filter(
(tool) =>
tool.status === "active" &&
(form.runtimeMode === "pipeline" ||
tool.type !== "system"),
)}
selectedIds={form.toolIds}
onChange={(toolIds) => updateForm("toolIds", toolIds)}
<ToolBindingEditor
tools={
form.runtimeMode === "realtime"
? tools.filter((tool) =>
realtimeToolFeatures?.externalTypes.includes(tool.type),
)
: tools
}
value={form.toolBindings}
variables={dynamicVariableDefinitions}
onChange={(toolBindings) =>
updateForm("toolBindings", toolBindings)
}
/>
</SectionCard>
</section>