feat(web): 工作台 - 优化 Agent 工作区与技能库

This commit is contained in:
ddcat666
2026-09-27 08:21:08 +08:00
parent b4111a8721
commit 5df5e09c63
22 changed files with 1681 additions and 196 deletions

View File

@@ -80,7 +80,9 @@ function unwrapTransportError(error: unknown): never {
code,
reason: error.response?.data?.reason,
details: error.response?.data?.details,
retryable: isRetryableStatus(status) || isRetryableStatus(code),
// 没有 response 的 AxiosError 代表请求没有拿到 HTTP 响应(断网、连接重置、DNS、超时等)。
// 这类错误不能靠 status 判断,但对保存来说通常是暂时性的,应交给上层有限退避重试。
retryable: status === undefined || isRetryableStatus(status) || isRetryableStatus(code),
retryAfterMs: retryAfterMilliseconds(error.response?.headers),
cause: error,
});

View File

@@ -26,7 +26,7 @@ export type Skill = {
contentHash: string;
fileCount: number;
totalBytes: number;
sourceType: "builtin" | "markdown" | "zip" | "github" | string;
sourceType: "builtin" | "markdown" | "zip" | string;
sourceUrl: string;
sourceRef: string;
sourceSubdir: string;
@@ -55,12 +55,32 @@ export type Skill = {
extraInfo: string;
isAdded: boolean;
isOwner: boolean;
libraryCategoryId?: string;
};
/** /skills/added 只返回运行时目录需要的引用字段,不携带编辑器和同步详情。 */
export type AddedSkillReference = Pick<Skill, "skillId" | "skillName" | "description" | "versionId" | "version" | "tag" | "isLike" | "isAdded" | "isOwner">;
export type AddedSkillReference = Pick<Skill, "skillId" | "skillName" | "description" | "versionId" | "version" | "tag" | "isLike" | "isAdded" | "isOwner" | "libraryCategoryId">;
export type SkillCategory = { value: string; label: string };
export type SkillCategory = { value: string; label: string; count?: number };
export type SkillLibraryCategory = {
id: string;
name: string;
scope: "personal" | "platform";
count: number;
};
export type SkillLibraryCategoryList = {
categories: SkillLibraryCategory[];
totalCount: number;
uncategorizedCount: number;
};
export type SkillLibraryCategoryMutationInput = {
name: string;
scope?: "personal" | "platform";
};
/**
* 场景预设:平台只读目录(GET /skills/presets,随二进制内置)。
@@ -95,6 +115,8 @@ export type ListSkillsInput = {
sort?: SkillSort;
search?: string;
tag?: string;
libraryCategoryId?: string;
libraryUncategorized?: boolean;
};
export type SkillMutationInput = {
@@ -158,6 +180,23 @@ export function listSkills(input: ListSkillsInput = {}) {
return http.get<SkillList>(`/skills?${params.toString()}`);
}
export function listSkillLibraryCategories(scope: "mine" | "created" = "mine") {
return http.get<SkillLibraryCategoryList>("/skills/library-categories", { params: { scope } });
}
export function createSkillLibraryCategory(input: SkillLibraryCategoryMutationInput) {
return http.post<{ category: SkillLibraryCategory }>("/skills/library-categories", input).finally(invalidateAddedSkillsCache);
}
export function deleteSkillLibraryCategory(id: string) {
return http.delete<{ deleted: boolean }>(`/skills/library-categories/${encodeURIComponent(id)}`).finally(invalidateAddedSkillsCache);
}
export function setSkillLibraryCategory(skillId: string, categoryId: string) {
return http.patch<{ skill: Skill }>(`/skills/${encodeURIComponent(skillId)}/library-category`, { categoryId }).finally(invalidateAddedSkillsCache);
}
export function getSkill(id: string) {
return http.get<{ skill: Skill }>(`/skills/${encodeURIComponent(id)}`);
}
@@ -237,6 +276,7 @@ function normalizeAddedSkillReference(skill: AddedSkillReference): Skill {
extraInfo: "",
isAdded: skill.isAdded,
isOwner: skill.isOwner,
libraryCategoryId: skill.libraryCategoryId || "",
};
}