Unify db api

This commit is contained in:
Xin Wang
2026-02-26 01:58:39 +08:00
parent 56f8aa2191
commit 72ed7d0512
40 changed files with 3926 additions and 593 deletions

View File

@@ -1,7 +1,11 @@
import { ASRModel, Assistant, CallLog, InteractionDetail, KnowledgeBase, KnowledgeDocument, LLMModel, Tool, Voice, Workflow, WorkflowEdge, WorkflowNode } from '../types';
import { apiRequest } from './apiClient';
import { apiRequest, getApiBaseUrl } from './apiClient';
type AnyRecord = Record<string, any>;
const DEFAULT_LIST_LIMIT = 1000;
const withLimit = (path: string, limit: number = DEFAULT_LIST_LIMIT): string =>
`${path}${path.includes('?') ? '&' : '?'}limit=${limit}`;
const readField = <T>(obj: AnyRecord, keys: string[], fallback: T): T => {
for (const key of keys) {
@@ -185,7 +189,8 @@ const mapKnowledgeBase = (raw: AnyRecord): KnowledgeBase => ({
const toHistoryRow = (raw: AnyRecord, assistantNameMap: Map<string, string>): CallLog => {
const assistantId = readField(raw, ['assistant_id', 'assistantId'], '');
const startTime = normalizeDateLabel(readField(raw, ['started_at', 'startTime'], ''));
const type = readField(raw, ['type'], 'text');
const rawType = String(readField(raw, ['type'], 'text')).toLowerCase();
const type: CallLog['type'] = rawType === 'audio' || rawType === 'video' ? rawType : 'text';
return {
id: String(readField(raw, ['id'], '')),
source: readField(raw, ['source'], 'debug') as 'debug' | 'external',
@@ -193,7 +198,7 @@ const toHistoryRow = (raw: AnyRecord, assistantNameMap: Map<string, string>): Ca
startTime,
duration: formatDuration(readField(raw, ['duration_seconds', 'durationSeconds'], 0)),
agentName: assistantNameMap.get(String(assistantId)) || String(assistantId || 'Unknown Assistant'),
type: type === 'audio' || type === 'video' ? type : 'text',
type,
details: [],
};
};
@@ -209,7 +214,7 @@ const toHistoryDetails = (raw: AnyRecord): InteractionDetail[] => {
};
export const fetchAssistants = async (): Promise<Assistant[]> => {
const response = await apiRequest<{ list?: AnyRecord[] } | AnyRecord[]>('/assistants');
const response = await apiRequest<{ list?: AnyRecord[] } | AnyRecord[]>(withLimit('/assistants'));
const list = Array.isArray(response) ? response : (response.list || []);
return list.map((item) => mapAssistant(item));
};
@@ -276,6 +281,8 @@ export const deleteAssistant = async (id: string): Promise<void> => {
export interface AssistantRuntimeConfigResponse {
assistantId: string;
configVersionId?: string;
assistant?: Record<string, any>;
sessionStartMetadata: Record<string, any>;
sources?: {
llmModelId?: string;
@@ -286,11 +293,11 @@ export interface AssistantRuntimeConfigResponse {
}
export const fetchAssistantRuntimeConfig = async (assistantId: string): Promise<AssistantRuntimeConfigResponse> => {
return apiRequest<AssistantRuntimeConfigResponse>(`/assistants/${assistantId}/runtime-config`);
return apiRequest<AssistantRuntimeConfigResponse>(`/assistants/${assistantId}/config`);
};
export const fetchVoices = async (): Promise<Voice[]> => {
const response = await apiRequest<{ list?: AnyRecord[] } | AnyRecord[]>('/voices');
const response = await apiRequest<{ list?: AnyRecord[] } | AnyRecord[]>(withLimit('/voices'));
const list = Array.isArray(response) ? response : (response.list || []);
return list.map((item) => mapVoice(item));
};
@@ -351,7 +358,7 @@ export const previewVoice = async (id: string, text: string, speed?: number, api
};
export const fetchASRModels = async (): Promise<ASRModel[]> => {
const response = await apiRequest<{ list?: AnyRecord[] } | AnyRecord[]>('/asr');
const response = await apiRequest<{ list?: AnyRecord[] } | AnyRecord[]>(withLimit('/asr'));
const list = Array.isArray(response) ? response : (response.list || []);
return list.map((item) => mapASRModel(item));
};
@@ -418,8 +425,7 @@ export const previewASRModel = async (
formData.append('api_key', options.apiKey);
}
const base = (import.meta.env.VITE_API_BASE_URL || 'http://127.0.0.1:8100/api').replace(/\/+$/, '');
const url = `${base}/asr/${id}/preview`;
const url = `${getApiBaseUrl()}/asr/${id}/preview`;
const response = await fetch(url, {
method: 'POST',
body: formData,
@@ -441,7 +447,7 @@ export const previewASRModel = async (
};
export const fetchLLMModels = async (): Promise<LLMModel[]> => {
const response = await apiRequest<{ list?: AnyRecord[] } | AnyRecord[]>('/llm');
const response = await apiRequest<{ list?: AnyRecord[] } | AnyRecord[]>(withLimit('/llm'));
const list = Array.isArray(response) ? response : (response.list || []);
return list.map((item) => mapLLMModel(item));
};
@@ -501,7 +507,7 @@ export const previewLLMModel = async (
};
export const fetchTools = async (): Promise<Tool[]> => {
const response = await apiRequest<{ list?: AnyRecord[] } | AnyRecord[]>('/tools/resources');
const response = await apiRequest<{ list?: AnyRecord[] } | AnyRecord[]>(withLimit('/tools/resources'));
const list = Array.isArray(response) ? response : (response.list || []);
return list.map((item) => mapTool(item));
};
@@ -544,18 +550,14 @@ export const deleteTool = async (id: string): Promise<void> => {
};
export const fetchWorkflows = async (): Promise<Workflow[]> => {
const response = await apiRequest<{ list?: AnyRecord[] } | AnyRecord[]>('/workflows');
const response = await apiRequest<{ list?: AnyRecord[] } | AnyRecord[]>(withLimit('/workflows'));
const list = Array.isArray(response) ? response : (response.list || []);
return list.map((item) => mapWorkflow(item));
};
export const fetchWorkflowById = async (id: string): Promise<Workflow> => {
const list = await fetchWorkflows();
const workflow = list.find((item) => item.id === id);
if (!workflow) {
throw new Error('Workflow not found');
}
return workflow;
const response = await apiRequest<AnyRecord>(`/workflows/${id}`);
return mapWorkflow(response);
};
export const createWorkflow = async (data: Partial<Workflow>): Promise<Workflow> => {
@@ -589,7 +591,7 @@ export const deleteWorkflow = async (id: string): Promise<void> => {
};
export const fetchKnowledgeBases = async (): Promise<KnowledgeBase[]> => {
const response = await apiRequest<{ list?: AnyRecord[] } | AnyRecord[]>('/knowledge/bases');
const response = await apiRequest<{ list?: AnyRecord[] } | AnyRecord[]>(withLimit('/knowledge/bases'));
const list = Array.isArray(response) ? response : (response.list || []);
return list.map((item) => mapKnowledgeBase(item));
};
@@ -641,8 +643,7 @@ export const uploadKnowledgeDocument = async (kbId: string, file: File): Promise
formData.append('size', `${file.size} bytes`);
formData.append('file_type', file.type || 'application/octet-stream');
const base = (import.meta.env.VITE_API_BASE_URL || 'http://127.0.0.1:8100/api').replace(/\/+$/, '');
const url = `${base}/knowledge/bases/${kbId}/documents`;
const url = `${getApiBaseUrl()}/knowledge/bases/${kbId}/documents`;
const response = await fetch(url, {
method: 'POST',
body: formData,
@@ -716,8 +717,8 @@ export const searchKnowledgeBase = async (
export const fetchHistory = async (): Promise<CallLog[]> => {
const [historyResp, assistantsResp] = await Promise.all([
apiRequest<{ list?: AnyRecord[] } | AnyRecord[]>('/history'),
apiRequest<{ list?: AnyRecord[] } | AnyRecord[]>('/assistants'),
apiRequest<{ list?: AnyRecord[] } | AnyRecord[]>(withLimit('/history')),
apiRequest<{ list?: AnyRecord[] } | AnyRecord[]>(withLimit('/assistants')),
]);
const assistantList = Array.isArray(assistantsResp) ? assistantsResp : (assistantsResp.list || []);