feat: add skill and assistant knowledge bases
This commit is contained in:
1 parent
dd0ee282df
commit
fbd8dec48f
45 files changed
+5262
-21
No files matched your search
@@ -0,0 +1,177 @@
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
|
||||
import { apiFetch } from "@/core/api/fetch-client";
|
||||
import { getBackendBaseURL } from "@/core/config";
|
||||
|
||||
const BASE = () => `${getBackendBaseURL()}/api/assistant-knowledge`;
|
||||
|
||||
export interface AssistantKnowledgeBase {
|
||||
id: string;
|
||||
name: string;
|
||||
status: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface AssistantWikiPage {
|
||||
id: string;
|
||||
slug: string;
|
||||
title: string;
|
||||
page_type: string;
|
||||
content_markdown: string;
|
||||
summary: string;
|
||||
current_revision_id?: string | null;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface AssistantWikiRevision {
|
||||
id: string;
|
||||
page_id: string;
|
||||
revision_no: number;
|
||||
summary: string;
|
||||
content_markdown: string;
|
||||
change_type: string;
|
||||
created_by?: string | null;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface AssistantKnowledgeSource {
|
||||
id: string;
|
||||
source_type: "weknora" | "skill" | "local_file";
|
||||
source_name: string;
|
||||
source_key: string;
|
||||
status: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface AssistantImportJob {
|
||||
id: string;
|
||||
source_id: string;
|
||||
trigger: string;
|
||||
status: string;
|
||||
phase: string;
|
||||
counts: Record<string, number>;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
async function readJson<T>(response: Response): Promise<T> {
|
||||
if (!response.ok) {
|
||||
const data = await response.json().catch(() => null);
|
||||
const detail = data && typeof data === "object" && "detail" in data
|
||||
? (data as { detail: unknown }).detail
|
||||
: `请求失败 (${response.status})`;
|
||||
throw new Error(typeof detail === "string" ? detail : JSON.stringify(detail));
|
||||
}
|
||||
return (await response.json()) as T;
|
||||
}
|
||||
|
||||
export async function getAssistantKnowledgeBase() {
|
||||
const data = await readJson<{ base: AssistantKnowledgeBase | null }>(await apiFetch(`${BASE()}/base`));
|
||||
return data.base;
|
||||
}
|
||||
|
||||
export async function initializeAssistantKnowledgeBase(name = "知识梳理") {
|
||||
const data = await readJson<{ base: AssistantKnowledgeBase }>(
|
||||
await apiFetch(`${BASE()}/base/initialize`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ name }),
|
||||
}),
|
||||
);
|
||||
return data.base;
|
||||
}
|
||||
|
||||
export async function listAssistantWikiPages(q = "") {
|
||||
const params = new URLSearchParams();
|
||||
if (q.trim()) params.set("q", q.trim());
|
||||
return (await readJson<{ pages: AssistantWikiPage[] }>(await apiFetch(`${BASE()}/wiki-pages?${params}`))).pages;
|
||||
}
|
||||
|
||||
export async function listAssistantKnowledgeSources() {
|
||||
return (await readJson<{ sources: AssistantKnowledgeSource[] }>(await apiFetch(`${BASE()}/sources`))).sources;
|
||||
}
|
||||
|
||||
export async function listAssistantImportJobs() {
|
||||
return (await readJson<{ jobs: AssistantImportJob[] }>(await apiFetch(`${BASE()}/import-jobs`))).jobs;
|
||||
}
|
||||
|
||||
export async function listAssistantWikiRevisions(slug: string) {
|
||||
return (await readJson<{ revisions: AssistantWikiRevision[] }>(
|
||||
await apiFetch(`${BASE()}/wiki-pages/${encodeURIComponent(slug)}/revisions`),
|
||||
)).revisions;
|
||||
}
|
||||
|
||||
export async function rollbackAssistantWikiRevision(slug: string, revisionId: string) {
|
||||
return readJson<AssistantWikiRevision>(
|
||||
await apiFetch(
|
||||
`${BASE()}/wiki-pages/${encodeURIComponent(slug)}/revisions/${encodeURIComponent(revisionId)}/rollback`,
|
||||
{ method: "POST" },
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
export async function uploadAssistantKnowledgeFiles(files: File[]) {
|
||||
const form = new FormData();
|
||||
files.forEach((file) => form.append("files", file));
|
||||
return readJson<{ batch_id: string; jobs: AssistantImportJob[] }>(
|
||||
await apiFetch(`${BASE()}/imports/files`, { method: "POST", body: form }),
|
||||
);
|
||||
}
|
||||
|
||||
export async function exportLlmWikiToAssistant(mappingId: string) {
|
||||
return readJson<AssistantImportJob>(
|
||||
await apiFetch(
|
||||
`${getBackendBaseURL()}/api/llmwiki/knowledge-bases/${encodeURIComponent(mappingId)}/export-to-assistant`,
|
||||
{ method: "POST" },
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
export async function reimportAssistantKnowledgeSource(sourceId: string) {
|
||||
return readJson<AssistantImportJob>(
|
||||
await apiFetch(`${BASE()}/sources/${encodeURIComponent(sourceId)}/reimport`, {
|
||||
method: "POST",
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
export async function deleteAssistantKnowledgeSource(sourceId: string) {
|
||||
const response = await apiFetch(`${BASE()}/sources/${encodeURIComponent(sourceId)}`, {
|
||||
method: "DELETE",
|
||||
});
|
||||
if (!response.ok) await readJson(response);
|
||||
}
|
||||
|
||||
const KEY = "assistant-knowledge";
|
||||
|
||||
export function useAssistantKnowledgeBase() {
|
||||
return useQuery({ queryKey: [KEY, "base"], queryFn: getAssistantKnowledgeBase });
|
||||
}
|
||||
|
||||
export function useAssistantWikiPages(query = "") {
|
||||
return useQuery({ queryKey: [KEY, "pages", query], queryFn: () => listAssistantWikiPages(query) });
|
||||
}
|
||||
|
||||
export function useAssistantKnowledgeSources() {
|
||||
return useQuery({ queryKey: [KEY, "sources"], queryFn: listAssistantKnowledgeSources });
|
||||
}
|
||||
|
||||
export function useAssistantImportJobs() {
|
||||
return useQuery({ queryKey: [KEY, "jobs"], queryFn: listAssistantImportJobs });
|
||||
}
|
||||
|
||||
export function useAssistantKnowledgeActions() {
|
||||
const client = useQueryClient();
|
||||
const invalidate = () => client.invalidateQueries({ queryKey: [KEY] });
|
||||
return {
|
||||
initialize: useMutation({ mutationFn: initializeAssistantKnowledgeBase, onSuccess: invalidate }),
|
||||
upload: useMutation({ mutationFn: uploadAssistantKnowledgeFiles, onSuccess: invalidate }),
|
||||
reimportSource: useMutation({ mutationFn: reimportAssistantKnowledgeSource, onSuccess: invalidate }),
|
||||
deleteSource: useMutation({ mutationFn: deleteAssistantKnowledgeSource, onSuccess: invalidate }),
|
||||
rollback: useMutation({
|
||||
mutationFn: ({ slug, revisionId }: { slug: string; revisionId: string }) =>
|
||||
rollbackAssistantWikiRevision(slug, revisionId),
|
||||
onSuccess: invalidate,
|
||||
}),
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user