refactor: update knowledge document types and API client interfaces
- Refactored types in `Knowledge/types.ts` to introduce new interfaces for document handling. - Added `KnowledgeDocItem`, `KnowledgeDocsListResponse`, `KnowledgeDocsUploadInput`, `KnowledgeDocsUploadResponse`, and `KnowledgeDocsDeleteResponse` for better structure and clarity. - Updated `KnowledgeDocsApiClient` interface to include methods for listing, uploading, and deleting documents. fix: replace deprecated icons in AccountSettingsPanel and SettingMenu - Replaced `CheckCircleIcon` with `CheckCircle` from `lucide-react` in `AccountSettingsPanel.tsx`. - Updated `SettingMenu.tsx` to use `Settings` and `User` from `lucide-react` instead of custom icons. test: add tests for knowledge docs routes and KnowledgePage - Created `knowledge-docs-routes.test.ts` to test API routes for listing, uploading, and deleting knowledge documents. - Added `knowledge-page.test.tsx` to test the rendering and functionality of the KnowledgePage component, including document loading and deletion.
This commit is contained in:
@@ -9,6 +9,7 @@ import { handleChannelRoutes } from './routes/channels';
|
||||
import { handleCronRoutes } from './routes/cron';
|
||||
import { handleFileRoutes } from './routes/files';
|
||||
import { handleGatewayRoutes } from './routes/gateway';
|
||||
import { handleKnowledgeRoutes } from './routes/knowledge';
|
||||
import { handleModelRoutes } from './routes/models';
|
||||
import { handleProviderRoutes } from './routes/providers';
|
||||
import { handleSessionRoutes } from './routes/sessions';
|
||||
@@ -25,6 +26,7 @@ const routeHandlers: RouteHandler[] = [
|
||||
handleModelRoutes,
|
||||
handleCronRoutes,
|
||||
handleGatewayRoutes,
|
||||
handleKnowledgeRoutes,
|
||||
handleFileRoutes,
|
||||
handleSessionRoutes,
|
||||
];
|
||||
|
||||
86
electron/api/routes/knowledge.ts
Normal file
86
electron/api/routes/knowledge.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
import type { HostApiContext } from '../context';
|
||||
import type { NormalizedHostApiRequest } from '../route-utils';
|
||||
import { fail, ok, parseJsonBody } from '../route-utils';
|
||||
import {
|
||||
deleteKnowledgeDoc,
|
||||
listKnowledgeDocs,
|
||||
uploadKnowledgeDoc,
|
||||
isSafeKnowledgeDocName,
|
||||
} from '../../utils/knowledge-docs';
|
||||
|
||||
function getDeleteTarget(request: NormalizedHostApiRequest): string | null {
|
||||
const fromQuery = request.url.searchParams.get('name')?.trim() || '';
|
||||
if (fromQuery) return fromQuery;
|
||||
|
||||
const body = request.body && typeof request.body === 'string'
|
||||
? parseJsonBody<{ fileName?: string; name?: string }>(request.body)
|
||||
: (request.body as { fileName?: string; name?: string } | null);
|
||||
|
||||
const candidate = String(body?.fileName || body?.name || '').trim();
|
||||
return candidate || null;
|
||||
}
|
||||
|
||||
export async function handleKnowledgeRoutes(
|
||||
request: NormalizedHostApiRequest,
|
||||
_ctx: HostApiContext,
|
||||
) {
|
||||
const { pathname, method } = request;
|
||||
|
||||
if (pathname === '/api/knowledge/docs' && method === 'GET') {
|
||||
try {
|
||||
return ok({
|
||||
success: true,
|
||||
files: await listKnowledgeDocs(),
|
||||
});
|
||||
} catch (error) {
|
||||
return fail(500, error instanceof Error ? error.message : String(error));
|
||||
}
|
||||
}
|
||||
|
||||
if (pathname === '/api/knowledge/docs' && method === 'POST') {
|
||||
try {
|
||||
const body = parseJsonBody<{ base64?: string; fileName?: string }>(request.body);
|
||||
const fileName = String(body?.fileName || '').trim();
|
||||
const base64 = String(body?.base64 || '').trim();
|
||||
|
||||
if (!fileName) {
|
||||
return fail(400, 'fileName is required');
|
||||
}
|
||||
if (!base64) {
|
||||
return fail(400, 'base64 is required');
|
||||
}
|
||||
if (!isSafeKnowledgeDocName(fileName)) {
|
||||
return fail(400, 'Invalid file name');
|
||||
}
|
||||
|
||||
return ok({
|
||||
success: true,
|
||||
file: await uploadKnowledgeDoc({ fileName, base64 }),
|
||||
});
|
||||
} catch (error) {
|
||||
return fail(500, error instanceof Error ? error.message : String(error));
|
||||
}
|
||||
}
|
||||
|
||||
if (method === 'DELETE' && (pathname === '/api/knowledge/docs' || pathname.startsWith('/api/knowledge/docs/'))) {
|
||||
try {
|
||||
const fileName = pathname.startsWith('/api/knowledge/docs/')
|
||||
? decodeURIComponent(pathname.slice('/api/knowledge/docs/'.length))
|
||||
: getDeleteTarget(request);
|
||||
|
||||
if (!fileName) {
|
||||
return fail(400, 'fileName is required');
|
||||
}
|
||||
if (!isSafeKnowledgeDocName(fileName)) {
|
||||
return fail(400, 'Invalid file name');
|
||||
}
|
||||
|
||||
await deleteKnowledgeDoc(fileName);
|
||||
return ok({ success: true });
|
||||
} catch (error) {
|
||||
return fail(500, error instanceof Error ? error.message : String(error));
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
Reference in New Issue
Block a user