refactor: replace skill code with skill ID across the application

- Updated skill handling to use skill IDs instead of skill codes in various components, services, and models.
- Modified tests to reflect changes in skill identification.
- Removed references to skill codes in favor of skill IDs for consistency and clarity.
- Updated localization files to remove skill code references and adjust error messages accordingly.
This commit is contained in:
mlogclub
2026-06-20 20:42:07 +08:00
parent 39c648f3c1
commit 541e4c5874
49 changed files with 258 additions and 341 deletions
@@ -122,7 +122,7 @@ export function AgentRunLogDetailDialog({
title={t("agentRunLog.planningStage")}
lines={[
`plannedAction: ${activeLog.plannedAction || "-"}`,
`plannedSkillCode: ${activeLog.plannedSkillCode || "-"}`,
`plannedSkillId: ${activeLog.plannedSkillId || "-"}`,
`plannedSkillName: ${activeLog.plannedSkillName || "-"}`,
`graphToolCode: ${activeLog.graphToolCode || "-"}`,
`recommendedAction: ${activeLog.recommendedAction || "-"}`,
+9 -4
View File
@@ -239,14 +239,19 @@ export default function DashboardAgentRunLogsPage() {
</div>
<div className="min-w-0 text-sm">
{item.plannedSkillCode || item.graphToolCode || item.plannedToolCode ? (
{item.plannedSkillId || item.graphToolCode || item.plannedToolCode ? (
<div className="min-w-0 space-y-1">
<div className="truncate font-medium">
{item.plannedSkillCode || item.graphToolCode || item.plannedToolCode}
{item.plannedSkillName ||
(item.plannedSkillId
? `Skill #${item.plannedSkillId}`
: "") ||
item.graphToolCode ||
item.plannedToolCode}
</div>
{item.plannedSkillName ? (
{item.plannedSkillId ? (
<div className="truncate text-xs text-muted-foreground">
{item.plannedSkillName}
Skill #{item.plannedSkillId}
</div>
) : item.handoffReason ? (
<div className="truncate text-xs text-muted-foreground">
@@ -33,7 +33,7 @@ import { useI18n } from "@/i18n/provider"
type DebugDialogProps = {
open: boolean
skillCode: string
skillDefinitionId: number
skillName: string
onOpenChange: (open: boolean) => void
}
@@ -96,7 +96,7 @@ function ResultBlock({
export function DebugDialog({
open,
skillCode,
skillDefinitionId,
skillName,
onOpenChange,
}: DebugDialogProps) {
@@ -106,9 +106,9 @@ export function DebugDialog({
return (
<DebugDialogBody
key={skillCode}
key={skillDefinitionId}
open={open}
skillCode={skillCode}
skillDefinitionId={skillDefinitionId}
skillName={skillName}
onOpenChange={onOpenChange}
/>
@@ -117,12 +117,12 @@ export function DebugDialog({
function DebugDialogBody({
open,
skillCode,
skillDefinitionId,
skillName,
onOpenChange,
}: DebugDialogProps) {
const t = useI18n()
const formId = `skill-debug-form-${skillCode}`
const formId = `skill-debug-form-${skillDefinitionId}`
const [running, setRunning] = useState(false)
const [resuming, setResuming] = useState(false)
const [aiAgents, setAiAgents] = useState<AIAgent[]>([])
@@ -198,7 +198,7 @@ function DebugDialogBody({
async function onSubmit(values: DebugForm) {
const payload: SkillDebugRunPayload = {
aiAgentId: Number(values.aiAgentId),
skillCode,
skillDefinitionId,
userMessage: values.userMessage.trim(),
}
const conversationId = Number(values.conversationId)
@@ -256,7 +256,7 @@ function DebugDialogBody({
<ProjectDialog
open={open}
onOpenChange={onOpenChange}
title={t("skillDefinition.debugTitle", { name: skillName || skillCode })}
title={t("skillDefinition.debugTitle", { name: skillName })}
description={t("skillDefinition.debugDescription")}
size="xl"
allowFullscreen
@@ -322,7 +322,7 @@ function DebugDialogBody({
<Field>
<FieldLabel>Skill</FieldLabel>
<FieldContent>
<Input value={skillCode} disabled />
<Input value={skillName} disabled />
</FieldContent>
</Field>
<Field>
@@ -359,7 +359,7 @@ function DebugDialogBody({
</CardHeader>
<CardContent className="space-y-3 text-sm">
<div className="flex flex-wrap gap-2">
<Badge variant="outline">{result?.skillCode || skillCode}</Badge>
<Badge variant="outline">{result?.skillName || skillName}</Badge>
{result?.graphToolCode ? (
<Badge variant="secondary">{result.graphToolCode}</Badge>
) : null}
@@ -522,7 +522,7 @@ function DebugDialogBody({
</CardHeader>
<CardContent className="space-y-3 text-sm">
<div className="flex flex-wrap gap-2">
<Badge variant="outline">{resumeResult.skillCode || skillCode}</Badge>
<Badge variant="outline">{resumeResult.skillName || skillName}</Badge>
{resumeResult.graphToolCode ? (
<Badge variant="secondary">{resumeResult.graphToolCode}</Badge>
) : null}
@@ -37,7 +37,6 @@ type SkillEditDialogProps = {
};
const emptyForm: EditForm = {
code: "",
name: "",
description: "",
instruction: "",
@@ -47,21 +46,15 @@ const emptyForm: EditForm = {
function createSkillFormSchema(t: TFunction) {
return z.object({
code: z
.string()
.trim()
.min(1, t("skillDefinition.codeRequired"))
.regex(/^[a-zA-Z0-9_-]+$/, t("skillDefinition.codeInvalid")),
name: z.string().trim().min(1, t("skillDefinition.nameRequired")),
description: z.string().trim(),
instruction: z.string().trim().min(1, t("skillDefinition.instructionRequired")),
examplesText: z.string().trim(),
remark: z.string().trim(),
name: z.string().trim().min(1, t("skillDefinition.nameRequired")),
description: z.string().trim(),
instruction: z.string().trim().min(1, t("skillDefinition.instructionRequired")),
examplesText: z.string().trim(),
remark: z.string().trim(),
});
}
type EditForm = {
code: string;
name: string;
description: string;
instruction: string;
@@ -75,7 +68,6 @@ function buildForm(item: SkillDefinition | null): EditForm {
}
return {
code: item.code,
name: item.name,
description: item.description ?? "",
instruction: item.instruction ?? "",
@@ -89,7 +81,6 @@ function buildPayload(
toolWhitelist: string[],
): CreateSkillDefinitionPayload {
return {
code: form.code.trim(),
name: form.name.trim(),
description: form.description.trim(),
instruction: form.instruction.trim(),
@@ -276,32 +267,18 @@ function SkillEditDialogBody({
onSubmit={handleSubmit(onFormSubmit)}
className="space-y-4"
>
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
<Field data-invalid={!!errors.code}>
<FieldLabel htmlFor="skill-code">{t("skillDefinition.code")}</FieldLabel>
<FieldContent>
<Input
id="skill-code"
placeholder={t("skillDefinition.codePlaceholder")}
aria-invalid={!!errors.code}
{...register("code")}
/>
<FieldError errors={[errors.code]} />
</FieldContent>
</Field>
<Field data-invalid={!!errors.name}>
<FieldLabel htmlFor="skill-name">{t("skillDefinition.name")}</FieldLabel>
<FieldContent>
<Input
id="skill-name"
placeholder={t("skillDefinition.namePlaceholder")}
aria-invalid={!!errors.name}
{...register("name")}
/>
<FieldError errors={[errors.name]} />
</FieldContent>
</Field>
</div>
<Field data-invalid={!!errors.name}>
<FieldLabel htmlFor="skill-name">{t("skillDefinition.name")}</FieldLabel>
<FieldContent>
<Input
id="skill-name"
placeholder={t("skillDefinition.namePlaceholder")}
aria-invalid={!!errors.name}
{...register("name")}
/>
<FieldError errors={[errors.name]} />
</FieldContent>
</Field>
<Field data-invalid={!!errors.description}>
<FieldLabel htmlFor="skill-description">{t("skillDefinition.description")}</FieldLabel>
+1 -11
View File
@@ -73,14 +73,6 @@ export default function DashboardSkillsPage() {
trim: true,
className: "w-full sm:w-72",
},
{
name: "code",
label: t("skillDefinition.filterCode"),
placeholder: t("skillDefinition.filterCode"),
defaultValue: "",
trim: true,
className: "w-full sm:w-56",
},
{
name: "status",
label: t("skillDefinition.allStatus"),
@@ -108,7 +100,6 @@ export default function DashboardSkillsPage() {
<div className="min-w-0">
<div className="flex flex-wrap items-center gap-2">
<div className="font-medium">{item.name}</div>
<Badge variant="outline">{item.code}</Badge>
<Badge variant="secondary">
{t("skillDefinition.whitelistCount", {
count: item.toolWhitelist.length,
@@ -185,7 +176,6 @@ export default function DashboardSkillsPage() {
fetchList={(query) =>
fetchSkillDefinitions({
name: typeof query.name === "string" ? query.name : undefined,
code: typeof query.code === "string" ? query.code : undefined,
status: typeof query.status === "number" ? query.status : undefined,
page: Number(query.page),
limit: Number(query.limit),
@@ -252,7 +242,7 @@ export default function DashboardSkillsPage() {
/>
<DebugDialog
open={debugDialogOpen}
skillCode={debuggingItem?.code ?? ""}
skillDefinitionId={debuggingItem?.id ?? 0}
skillName={debuggingItem?.name ?? ""}
onOpenChange={(open) => {
if (!open) setDebuggingItem(null);
+4 -6
View File
@@ -232,7 +232,7 @@ export type AIAgent = {
knowledgeIds: number[]
knowledgeBaseNames: string[]
skillIds: number[]
skills: { id: number; code: string; name: string }[]
skills: { id: number; name: string }[]
directTools: {
toolCode: string
serverCode: string
@@ -292,7 +292,6 @@ export type UpdateAdminQuickReplyPayload = CreateAdminQuickReplyPayload & {
export type SkillDefinition = {
id: number
code: string
name: string
description: string
instruction: string
@@ -308,7 +307,6 @@ export type SkillDefinition = {
}
export type CreateSkillDefinitionPayload = {
code: string
name: string
description: string
instruction: string
@@ -324,7 +322,7 @@ export type UpdateSkillDefinitionPayload = CreateSkillDefinitionPayload & {
export type SkillDebugRunPayload = {
aiAgentId: number
conversationId?: number
skillCode: string
skillDefinitionId: number
userMessage: string
}
@@ -336,7 +334,7 @@ export type SkillDebugResumePayload = {
}
export type SkillDebugRunResult = {
skillCode: string
skillDefinitionId: number
skillName: string
replyText: string
planReason: string
@@ -415,7 +413,7 @@ export type AgentRunLog = {
aiConfigId: number
userMessage: string
plannedAction: string
plannedSkillCode: string
plannedSkillId: number
plannedSkillName: string
skillRouteTrace: string
toolSearchTrace: string
-5
View File
@@ -1612,7 +1612,6 @@
"refresh": "Refresh",
"new": "New",
"filterName": "Filter by name",
"filterCode": "Filter by code",
"searchStatus": "Search statuses",
"emptyStatus": "No matching statuses",
"query": "Search",
@@ -1621,8 +1620,6 @@
"actions": "Actions",
"loadingRows": "Loading skills...",
"emptyRows": "No matching skills",
"codeRequired": "Enter a skill code.",
"codeInvalid": "Skill codes can contain letters, numbers, underscores, and hyphens only.",
"nameRequired": "Enter a skill name.",
"instructionRequired": "Enter skill instructions.",
"editTitle": "Edit",
@@ -1632,8 +1629,6 @@
"save": "Save",
"create": "Create",
"loading": "Loading...",
"code": "Code",
"codePlaceholder": "Example: refund_skill",
"name": "Name",
"namePlaceholder": "Example: Refund Handling",
"description": "Description",
-5
View File
@@ -1613,7 +1613,6 @@
"refresh": "刷新",
"new": "新建",
"filterName": "按名称筛选",
"filterCode": "按编码筛选",
"searchStatus": "搜索状态",
"emptyStatus": "未找到状态",
"query": "查询",
@@ -1622,8 +1621,6 @@
"actions": "操作",
"loadingRows": "正在加载 Skill...",
"emptyRows": "没有匹配的 Skill",
"codeRequired": "Skill 编码不能为空",
"codeInvalid": "Skill 编码仅支持字母、数字、下划线和中划线",
"nameRequired": "Skill 名称不能为空",
"instructionRequired": "技能说明不能为空",
"editTitle": "编辑",
@@ -1633,8 +1630,6 @@
"save": "保存",
"create": "创建",
"loading": "加载中...",
"code": "编码",
"codePlaceholder": "例如:refund_skill",
"name": "名称",
"namePlaceholder": "例如:退款处理",
"description": "描述",