feat: add output schema handling and display in NodeConfigPanel; implement buildVariableSpecDisplay function
This commit is contained in:
@@ -12,6 +12,7 @@ import { cn } from "@/lib/utils"
|
|||||||
|
|
||||||
import { VariableSelector } from "./variable-selector"
|
import { VariableSelector } from "./variable-selector"
|
||||||
import {
|
import {
|
||||||
|
buildVariableSpecDisplay,
|
||||||
createConditionBranchID,
|
createConditionBranchID,
|
||||||
isRefValue,
|
isRefValue,
|
||||||
normalizeNodeConfig,
|
normalizeNodeConfig,
|
||||||
@@ -73,6 +74,7 @@ export function NodeConfigPanel({
|
|||||||
|
|
||||||
const inputsValues = node.data?.inputsValues ?? {}
|
const inputsValues = node.data?.inputsValues ?? {}
|
||||||
const inputSchema = nodeSpec?.inputSchema ?? []
|
const inputSchema = nodeSpec?.inputSchema ?? []
|
||||||
|
const outputSchema = nodeSpec?.outputSchema ?? []
|
||||||
const canDelete = node.type !== "start" && node.type !== "end"
|
const canDelete = node.type !== "start" && node.type !== "end"
|
||||||
const config = normalizeNodeConfig(node.data?.config)
|
const config = normalizeNodeConfig(node.data?.config)
|
||||||
const branches = config.branches ?? []
|
const branches = config.branches ?? []
|
||||||
@@ -175,6 +177,25 @@ export function NodeConfigPanel({
|
|||||||
onDelete={deleteBranch}
|
onDelete={deleteBranch}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
|
{outputSchema.length > 0 ? (
|
||||||
|
<ConfigCard title="输出" meta={`${outputSchema.length} 项`}>
|
||||||
|
<div className="space-y-2">
|
||||||
|
{outputSchema.map((output) => {
|
||||||
|
const item = buildVariableSpecDisplay(output)
|
||||||
|
return (
|
||||||
|
<div key={item.key} className="rounded-md border border-slate-200 bg-slate-50/60 px-2.5 py-2">
|
||||||
|
<div className="truncate text-xs font-medium text-slate-700">{item.label}</div>
|
||||||
|
<div className="mt-1 truncate font-mono text-[11px] leading-4 text-slate-500">{item.subtitle}</div>
|
||||||
|
{item.description ? (
|
||||||
|
<div className="mt-1 text-xs leading-4 text-muted-foreground">{item.description}</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</ConfigCard>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -244,6 +244,22 @@ describe("workflow variable display helpers", () => {
|
|||||||
description: "客户本轮发送的消息内容",
|
description: "客户本轮发送的消息内容",
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("builds variable spec display rows for readonly node outputs", async () => {
|
||||||
|
const { buildVariableSpecDisplay } = await loadModule()
|
||||||
|
|
||||||
|
assert.deepEqual(plain(buildVariableSpecDisplay({
|
||||||
|
name: "replyText",
|
||||||
|
label: "回复内容",
|
||||||
|
type: "string",
|
||||||
|
description: "发送给客户的最终回复文本",
|
||||||
|
})), {
|
||||||
|
key: "replyText",
|
||||||
|
label: "回复内容",
|
||||||
|
subtitle: "replyText · string",
|
||||||
|
description: "发送给客户的最终回复文本",
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("workflow definition mutations", () => {
|
describe("workflow definition mutations", () => {
|
||||||
|
|||||||
@@ -72,6 +72,13 @@ export type WorkflowVariableOption = {
|
|||||||
description: string
|
description: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type WorkflowVariableSpecDisplay = {
|
||||||
|
key: string
|
||||||
|
label: string
|
||||||
|
subtitle: string
|
||||||
|
description: string
|
||||||
|
}
|
||||||
|
|
||||||
export type WorkflowNodeSpec = AIWorkflowNodeSpec
|
export type WorkflowNodeSpec = AIWorkflowNodeSpec
|
||||||
|
|
||||||
export type WorkflowDraftValidation = {
|
export type WorkflowDraftValidation = {
|
||||||
@@ -110,6 +117,15 @@ export function buildVariableOption(variable: WorkflowVariableRef): WorkflowVari
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function buildVariableSpecDisplay(variable: WorkflowVariableSpec): WorkflowVariableSpecDisplay {
|
||||||
|
return {
|
||||||
|
key: variable.name,
|
||||||
|
label: variable.label || variable.name,
|
||||||
|
subtitle: [variable.name, variable.type].filter(Boolean).join(" · "),
|
||||||
|
description: variable.description || "",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function getNodeTitle(
|
export function getNodeTitle(
|
||||||
node: AIWorkflowDefinition["nodes"][number] | undefined,
|
node: AIWorkflowDefinition["nodes"][number] | undefined,
|
||||||
specs: AIWorkflowNodeSpec[] = []
|
specs: AIWorkflowNodeSpec[] = []
|
||||||
|
|||||||
Reference in New Issue
Block a user