refactor: unify system tools as resources
This commit is contained in:
@@ -184,7 +184,6 @@ function blankPromptForm(name: string): AssistantForm {
|
||||
actions: [],
|
||||
openingMessage: null,
|
||||
},
|
||||
systemTools: [],
|
||||
visionEnabled: false,
|
||||
visionModelResourceId: "",
|
||||
toolIds: [],
|
||||
@@ -480,7 +479,6 @@ export function AssistantPage(props: AssistantPageProps) {
|
||||
actions: a.startup?.actions ?? [],
|
||||
openingMessage: a.startup?.openingMessage ?? null,
|
||||
},
|
||||
systemTools: a.systemTools ?? [],
|
||||
visionEnabled: a.visionEnabled,
|
||||
visionModelResourceId: a.visionModelResourceId ?? "",
|
||||
toolIds: a.toolIds ?? [],
|
||||
@@ -557,7 +555,6 @@ export function AssistantPage(props: AssistantPageProps) {
|
||||
actions: [],
|
||||
openingMessage: null,
|
||||
},
|
||||
systemTools: [],
|
||||
visionEnabled: false,
|
||||
visionModelResourceId: null,
|
||||
modelResourceIds: {},
|
||||
@@ -617,7 +614,6 @@ export function AssistantPage(props: AssistantPageProps) {
|
||||
enableInterrupt: form.enableInterrupt,
|
||||
turnConfig: form.turnConfig,
|
||||
startup: form.startup,
|
||||
systemTools: form.runtimeMode === "pipeline" ? form.systemTools : [],
|
||||
visionEnabled: form.visionEnabled,
|
||||
visionModelResourceId: form.visionModelResourceId || null,
|
||||
modelResourceIds: {
|
||||
@@ -1304,10 +1300,16 @@ export function AssistantPage(props: AssistantPageProps) {
|
||||
vision: visionModelOptionsFor(""),
|
||||
}}
|
||||
toolOptions={tools
|
||||
.filter(
|
||||
(tool) => tool.status === "active" && tool.type !== "system",
|
||||
)
|
||||
.map((tool) => ({ value: tool.id, label: tool.name }))}
|
||||
.filter((tool) => tool.status === "active")
|
||||
.map((tool) => ({
|
||||
value: tool.id,
|
||||
label: tool.name,
|
||||
toolType: tool.type,
|
||||
systemKind:
|
||||
tool.definition.type === "system"
|
||||
? tool.definition.config.kind
|
||||
: undefined,
|
||||
}))}
|
||||
knowledgeOptions={kbOptions}
|
||||
onBack={() => router.push("/assistants")}
|
||||
onSave={() => void handleSaveWorkflow()}
|
||||
|
||||
@@ -57,12 +57,14 @@ import {
|
||||
type ClientToolResponseWaitMode,
|
||||
type HttpToolDefinition,
|
||||
type McpServer,
|
||||
type SystemToolKind,
|
||||
type Tool,
|
||||
type ToolParameter,
|
||||
type ToolExecutionMode,
|
||||
type ToolStatus,
|
||||
type ToolUpsert,
|
||||
} from "@/lib/api";
|
||||
import { SYSTEM_TOOL_OPTIONS } from "@/lib/system-tools";
|
||||
|
||||
type ToolKind = "system" | "http" | "client";
|
||||
type HttpMethod = HttpToolDefinition["config"]["method"];
|
||||
@@ -86,6 +88,7 @@ type ToolForm = {
|
||||
type: ToolKind;
|
||||
description: string;
|
||||
status: ToolStatus;
|
||||
systemKind: SystemToolKind;
|
||||
messageType: "none" | "custom";
|
||||
customMessage: string;
|
||||
captureReason: boolean;
|
||||
@@ -115,6 +118,7 @@ function blankForm(): ToolForm {
|
||||
type: "system",
|
||||
description: "",
|
||||
status: "active",
|
||||
systemKind: "end_conversation",
|
||||
messageType: "none",
|
||||
customMessage: "",
|
||||
captureReason: true,
|
||||
@@ -148,6 +152,7 @@ function formFromTool(tool: Tool): ToolForm {
|
||||
base.description = tool.description;
|
||||
base.status = tool.status;
|
||||
if (tool.definition.type === "system") {
|
||||
base.systemKind = tool.definition.config.kind;
|
||||
base.messageType = tool.definition.config.messageType;
|
||||
base.customMessage = tool.definition.config.customMessage;
|
||||
base.captureReason = tool.definition.config.captureReason;
|
||||
@@ -246,9 +251,13 @@ function payloadFromForm(form: ToolForm): ToolUpsert {
|
||||
schemaVersion: 1,
|
||||
type: "system",
|
||||
config: {
|
||||
kind: "end_conversation",
|
||||
kind: form.systemKind,
|
||||
messageType: form.messageType,
|
||||
customMessage: form.messageType === "custom" ? form.customMessage : "",
|
||||
customMessage:
|
||||
form.systemKind === "end_conversation" &&
|
||||
form.messageType === "custom"
|
||||
? form.customMessage
|
||||
: "",
|
||||
captureReason: form.captureReason,
|
||||
},
|
||||
},
|
||||
@@ -871,52 +880,80 @@ function SystemToolFields({
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<Field label="系统动作">
|
||||
<Select value="end_conversation" disabled>
|
||||
<Select
|
||||
value={form.systemKind}
|
||||
onValueChange={(systemKind: SystemToolKind) =>
|
||||
setForm((current) => ({
|
||||
...current,
|
||||
systemKind,
|
||||
functionName: systemKind,
|
||||
}))
|
||||
}
|
||||
>
|
||||
<SelectTrigger className="w-full border-hairline-strong bg-background">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="end_conversation">结束对话</SelectItem>
|
||||
{SYSTEM_TOOL_OPTIONS.map((option) => (
|
||||
<SelectItem key={option.value} value={option.value}>
|
||||
{option.label}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</Field>
|
||||
<Field label="结束语">
|
||||
<Select
|
||||
value={form.messageType}
|
||||
onValueChange={(messageType: "none" | "custom") =>
|
||||
setForm((current) => ({ ...current, messageType }))
|
||||
}
|
||||
>
|
||||
<SelectTrigger className="w-full border-hairline-strong bg-background"><SelectValue /></SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="none">不播放固定结束语</SelectItem>
|
||||
<SelectItem value="custom">自定义结束语</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</Field>
|
||||
{form.messageType === "custom" && (
|
||||
<Field label="自定义结束语">
|
||||
<Textarea
|
||||
value={form.customMessage}
|
||||
onChange={(event) =>
|
||||
setForm((current) => ({ ...current, customMessage: event.target.value }))
|
||||
}
|
||||
rows={3}
|
||||
/>
|
||||
</Field>
|
||||
<p className="text-xs leading-5 text-muted-foreground">
|
||||
{SYSTEM_TOOL_OPTIONS.find((option) => option.value === form.systemKind)
|
||||
?.description ?? "由平台执行的会话控制能力。"}
|
||||
</p>
|
||||
{form.systemKind === "end_conversation" && (
|
||||
<>
|
||||
<Field label="结束语">
|
||||
<Select
|
||||
value={form.messageType}
|
||||
onValueChange={(messageType: "none" | "custom") =>
|
||||
setForm((current) => ({ ...current, messageType }))
|
||||
}
|
||||
>
|
||||
<SelectTrigger className="w-full border-hairline-strong bg-background">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="none">不播放固定结束语</SelectItem>
|
||||
<SelectItem value="custom">自定义结束语</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</Field>
|
||||
{form.messageType === "custom" && (
|
||||
<Field label="自定义结束语">
|
||||
<Textarea
|
||||
value={form.customMessage}
|
||||
onChange={(event) =>
|
||||
setForm((current) => ({
|
||||
...current,
|
||||
customMessage: event.target.value,
|
||||
}))
|
||||
}
|
||||
rows={3}
|
||||
/>
|
||||
</Field>
|
||||
)}
|
||||
<div className="flex items-center justify-between gap-4 rounded-lg border border-hairline-strong px-4 py-3">
|
||||
<div>
|
||||
<div className="font-medium text-foreground">记录结束原因</div>
|
||||
<div className="mt-0.5 text-xs text-muted-foreground">
|
||||
要求模型在调用时提供 reason 参数
|
||||
</div>
|
||||
</div>
|
||||
<Switch
|
||||
checked={form.captureReason}
|
||||
onCheckedChange={(captureReason) =>
|
||||
setForm((current) => ({ ...current, captureReason }))
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<div className="flex items-center justify-between gap-4 rounded-lg border border-hairline-strong px-4 py-3">
|
||||
<div>
|
||||
<div className="font-medium text-foreground">记录结束原因</div>
|
||||
<div className="mt-0.5 text-xs text-muted-foreground">要求模型在调用时提供 reason 参数</div>
|
||||
</div>
|
||||
<Switch
|
||||
checked={form.captureReason}
|
||||
onCheckedChange={(captureReason) =>
|
||||
setForm((current) => ({ ...current, captureReason }))
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user