refactor: unify system tools as resources
This commit is contained in:
@@ -8,7 +8,6 @@ import {
|
||||
ChevronLeft,
|
||||
Copy,
|
||||
Pencil,
|
||||
PhoneOff,
|
||||
Plus,
|
||||
ServerCog,
|
||||
Settings2,
|
||||
@@ -19,7 +18,6 @@ import {
|
||||
} from "lucide-react";
|
||||
|
||||
import { HelpHint } from "@/components/editor/section-card";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Dialog,
|
||||
@@ -47,10 +45,8 @@ import {
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import type {
|
||||
KnowledgeRetrievalConfig,
|
||||
SystemToolKind,
|
||||
Tool,
|
||||
} from "@/lib/api";
|
||||
import { SYSTEM_TOOL_OPTIONS } from "@/lib/system-tools";
|
||||
|
||||
import type { RuntimeMode } from "./types";
|
||||
|
||||
@@ -487,34 +483,20 @@ export function ToolPicker({
|
||||
tools,
|
||||
selectedIds,
|
||||
onChange,
|
||||
selectedSystemTools,
|
||||
onSystemToolsChange,
|
||||
showBuiltInSystemTools,
|
||||
}: {
|
||||
tools: Tool[];
|
||||
selectedIds: string[];
|
||||
onChange: (ids: string[]) => void;
|
||||
selectedSystemTools: SystemToolKind[];
|
||||
onSystemToolsChange: (tools: SystemToolKind[]) => void;
|
||||
showBuiltInSystemTools: boolean;
|
||||
}) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [activeTab, setActiveTab] = useState<Tool["type"]>("system");
|
||||
const [draftIds, setDraftIds] = useState<string[]>(selectedIds);
|
||||
const [draftSystemTools, setDraftSystemTools] =
|
||||
useState<SystemToolKind[]>(selectedSystemTools);
|
||||
const selectedTools = selectedIds
|
||||
.map((id) => tools.find((tool) => tool.id === id))
|
||||
.filter((tool): tool is Tool => Boolean(tool));
|
||||
const selectedBuiltInTools = selectedSystemTools
|
||||
.map((kind) => SYSTEM_TOOL_OPTIONS.find((option) => option.value === kind))
|
||||
.filter((option): option is (typeof SYSTEM_TOOL_OPTIONS)[number] =>
|
||||
Boolean(option),
|
||||
);
|
||||
|
||||
function openPicker() {
|
||||
setDraftIds(selectedIds);
|
||||
setDraftSystemTools(selectedSystemTools);
|
||||
setOpen(true);
|
||||
}
|
||||
|
||||
@@ -526,14 +508,6 @@ export function ToolPicker({
|
||||
);
|
||||
}
|
||||
|
||||
function toggleBuiltInTool(kind: SystemToolKind) {
|
||||
setDraftSystemTools((current) =>
|
||||
current.includes(kind)
|
||||
? current.filter((item) => item !== kind)
|
||||
: [...current, kind],
|
||||
);
|
||||
}
|
||||
|
||||
const tabs: Array<{ value: Tool["type"]; label: string }> = [
|
||||
{ value: "system", label: "System" },
|
||||
{ value: "http", label: "HTTP" },
|
||||
@@ -544,34 +518,13 @@ export function ToolPicker({
|
||||
return (
|
||||
<>
|
||||
<div className="flex min-h-9 flex-wrap items-center gap-2">
|
||||
{selectedBuiltInTools.map((tool) => (
|
||||
<div
|
||||
key={`built-in-${tool.value}`}
|
||||
className="flex h-8 items-center gap-2 rounded-lg border border-hairline-strong bg-background px-2.5 text-sm"
|
||||
>
|
||||
<Sparkles size={14} />
|
||||
<span className="max-w-48 truncate">{tool.label}</span>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() =>
|
||||
onSystemToolsChange(
|
||||
selectedSystemTools.filter((kind) => kind !== tool.value),
|
||||
)
|
||||
}
|
||||
className="text-muted-soft transition-colors hover:text-foreground"
|
||||
aria-label={`移除系统工具 ${tool.label}`}
|
||||
>
|
||||
<X size={13} />
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
{selectedTools.map((tool) => (
|
||||
<div
|
||||
key={tool.id}
|
||||
className="flex h-8 items-center gap-2 rounded-lg border border-hairline-strong bg-background px-2.5 text-sm"
|
||||
>
|
||||
{tool.type === "system" ? (
|
||||
<PhoneOff size={14} />
|
||||
<Sparkles size={14} />
|
||||
) : tool.type === "mcp" ? (
|
||||
<ServerCog size={14} />
|
||||
) : (
|
||||
@@ -606,7 +559,7 @@ export function ToolPicker({
|
||||
<DialogHeader>
|
||||
<DialogTitle>选择工具</DialogTitle>
|
||||
<DialogDescription>
|
||||
按类型选择内置系统工具或已经启用的工具资源。
|
||||
按类型选择已经启用的工具资源。
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
@@ -631,9 +584,7 @@ export function ToolPicker({
|
||||
|
||||
{tabs.map((tab) => {
|
||||
const resources = tools.filter((tool) => tool.type === tab.value);
|
||||
const hasBuiltIns =
|
||||
tab.value === "system" && showBuiltInSystemTools;
|
||||
const isEmpty = resources.length === 0 && !hasBuiltIns;
|
||||
const isEmpty = resources.length === 0;
|
||||
|
||||
return (
|
||||
<TabsContent key={tab.value} value={tab.value} className="pt-3">
|
||||
@@ -643,35 +594,6 @@ export function ToolPicker({
|
||||
</div>
|
||||
) : (
|
||||
<div className="max-h-[280px] divide-y divide-hairline overflow-y-auto rounded-xl border border-hairline">
|
||||
{hasBuiltIns &&
|
||||
SYSTEM_TOOL_OPTIONS.map((option) => {
|
||||
const checked = draftSystemTools.includes(option.value);
|
||||
return (
|
||||
<label
|
||||
key={`built-in-${option.value}`}
|
||||
className="flex h-14 cursor-pointer items-center gap-3 px-4 transition-colors hover:bg-surface-strong/40"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={checked}
|
||||
onChange={() => toggleBuiltInTool(option.value)}
|
||||
className="size-4 accent-primary"
|
||||
/>
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="truncate font-medium text-foreground">
|
||||
{option.label}
|
||||
</span>
|
||||
<Badge variant="secondary">内置</Badge>
|
||||
</div>
|
||||
<div className="mt-0.5 truncate text-xs text-muted-foreground">
|
||||
{option.description}
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
);
|
||||
})}
|
||||
|
||||
{resources.map((tool) => {
|
||||
const checked = draftIds.includes(tool.id);
|
||||
return (
|
||||
@@ -686,13 +608,8 @@ export function ToolPicker({
|
||||
className="size-4 accent-primary"
|
||||
/>
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="truncate font-medium text-foreground">
|
||||
{tool.name}
|
||||
</span>
|
||||
{tool.type === "system" && (
|
||||
<Badge variant="secondary">资源</Badge>
|
||||
)}
|
||||
<div className="truncate font-medium text-foreground">
|
||||
{tool.name}
|
||||
</div>
|
||||
<div className="mt-0.5 truncate font-mono text-xs text-muted-foreground">
|
||||
{tool.functionName}
|
||||
@@ -715,7 +632,6 @@ export function ToolPicker({
|
||||
<Button
|
||||
onClick={() => {
|
||||
onChange(draftIds);
|
||||
onSystemToolsChange(draftSystemTools);
|
||||
setOpen(false);
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -506,8 +506,15 @@ export function PromptEditor({
|
||||
openingMessage: null,
|
||||
});
|
||||
}
|
||||
if (runtimeMode === "realtime" && form.systemTools.length) {
|
||||
updateForm("systemTools", []);
|
||||
if (runtimeMode === "realtime") {
|
||||
updateForm(
|
||||
"toolIds",
|
||||
form.toolIds.filter(
|
||||
(id) =>
|
||||
tools.find((tool) => tool.id === id)?.type !==
|
||||
"system",
|
||||
),
|
||||
);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
@@ -602,14 +609,13 @@ export function PromptEditor({
|
||||
description="配置该提示词助手可以调用的工具"
|
||||
>
|
||||
<ToolPicker
|
||||
tools={tools.filter((tool) => tool.status === "active")}
|
||||
tools={tools.filter(
|
||||
(tool) =>
|
||||
tool.status === "active" &&
|
||||
(form.runtimeMode === "pipeline" || tool.type !== "system"),
|
||||
)}
|
||||
selectedIds={form.toolIds}
|
||||
onChange={(toolIds) => updateForm("toolIds", toolIds)}
|
||||
selectedSystemTools={form.systemTools}
|
||||
onSystemToolsChange={(systemTools) =>
|
||||
updateForm("systemTools", systemTools)
|
||||
}
|
||||
showBuiltInSystemTools={form.runtimeMode === "pipeline"}
|
||||
/>
|
||||
</SectionCard>
|
||||
</section>
|
||||
|
||||
@@ -2,7 +2,6 @@ import type {
|
||||
DynamicVariableDefinition,
|
||||
KnowledgeRetrievalConfig,
|
||||
StartupConfig,
|
||||
SystemToolKind,
|
||||
TurnConfig,
|
||||
} from "@/lib/api";
|
||||
|
||||
@@ -23,7 +22,6 @@ export type AssistantForm = {
|
||||
enableInterrupt: boolean;
|
||||
turnConfig: TurnConfig;
|
||||
startup: StartupConfig;
|
||||
systemTools: SystemToolKind[];
|
||||
visionEnabled: boolean;
|
||||
visionModelResourceId: string;
|
||||
toolIds: string[];
|
||||
|
||||
Reference in New Issue
Block a user