2131 lines
50 KiB
TypeScript
2131 lines
50 KiB
TypeScript
import { requestClient } from '#/api/request';
|
|
import { streamRequestClient } from '#/api/stream-request';
|
|
|
|
/**
|
|
* AI 平台 API
|
|
*/
|
|
|
|
const BASE_URL = `/api/ai`;
|
|
|
|
// ============ 类型定义 ============
|
|
|
|
/** 提供商类型 */
|
|
export interface ProviderType {
|
|
type: string;
|
|
name: string;
|
|
}
|
|
|
|
/** 提供商 */
|
|
export interface LLMProvider {
|
|
id: string;
|
|
name: string;
|
|
provider_type: string;
|
|
api_key_masked: string;
|
|
api_base: string;
|
|
api_version: string;
|
|
ollama_host: string;
|
|
description: string;
|
|
is_active: boolean;
|
|
quota_limit: number;
|
|
quota_used: number;
|
|
created_at: string;
|
|
}
|
|
|
|
/** 提供商列表项 */
|
|
export interface ProviderListItem {
|
|
id: string;
|
|
name: string;
|
|
provider_type: string;
|
|
is_active: boolean;
|
|
description: string;
|
|
created_at: string;
|
|
}
|
|
|
|
/** 创建提供商 */
|
|
export interface ProviderCreateInput {
|
|
name: string;
|
|
provider_type: string;
|
|
api_key?: string;
|
|
api_base?: string;
|
|
api_version?: string;
|
|
ollama_host?: string;
|
|
description?: string;
|
|
is_active?: boolean;
|
|
}
|
|
|
|
/** 模型 */
|
|
export interface LLMModel {
|
|
id: string;
|
|
provider_id: string;
|
|
provider_name: string;
|
|
model_name: string;
|
|
display_name: string;
|
|
model_type: string;
|
|
max_tokens: number;
|
|
context_window: number;
|
|
default_temperature: number;
|
|
default_top_p: number;
|
|
input_price: number;
|
|
output_price: number;
|
|
supports_vision: boolean;
|
|
supports_function_call: boolean;
|
|
supports_streaming: boolean;
|
|
is_active: boolean;
|
|
created_at: string;
|
|
}
|
|
|
|
/** 模型列表项 */
|
|
export interface ModelListItem {
|
|
id: string;
|
|
provider_id: string;
|
|
provider_name: string;
|
|
model_name: string;
|
|
display_name: string;
|
|
model_type: string;
|
|
is_active: boolean;
|
|
}
|
|
|
|
/** 创建模型 */
|
|
export interface ModelCreateInput {
|
|
provider_id: string;
|
|
model_name: string;
|
|
display_name: string;
|
|
model_type?: string;
|
|
max_tokens?: number;
|
|
context_window?: number;
|
|
default_temperature?: number;
|
|
default_top_p?: number;
|
|
input_price?: number;
|
|
output_price?: number;
|
|
supports_vision?: boolean;
|
|
supports_function_call?: boolean;
|
|
supports_streaming?: boolean;
|
|
is_active?: boolean;
|
|
}
|
|
|
|
/** 默认模型信息 */
|
|
export interface DefaultModel {
|
|
model_name: string;
|
|
display_name: string;
|
|
model_type: string;
|
|
max_tokens: number;
|
|
context_window: number;
|
|
supports_vision?: boolean;
|
|
supports_function_call?: boolean;
|
|
input_price?: number;
|
|
output_price?: number;
|
|
}
|
|
|
|
/** AI 应用 */
|
|
export interface AIApp {
|
|
id: string;
|
|
name: string;
|
|
code: string;
|
|
description: string;
|
|
icon: string;
|
|
app_type: 'agent' | 'chat' | 'completion' | 'workflow';
|
|
status: 'disabled' | 'draft' | 'published';
|
|
model_id: null | string;
|
|
model_name: string;
|
|
system_prompt: string;
|
|
temperature: number;
|
|
top_p: number;
|
|
max_tokens: number;
|
|
opening_statement: string;
|
|
suggested_questions: string[];
|
|
workflow_definition: Record<string, any>;
|
|
is_public: boolean;
|
|
conversation_count: number;
|
|
message_count: number;
|
|
sort?: number;
|
|
sys_create_datetime?: string;
|
|
sys_update_datetime?: string;
|
|
}
|
|
|
|
/** 应用列表项 */
|
|
export interface AppListItem {
|
|
id: string;
|
|
name: string;
|
|
code: string;
|
|
description: string;
|
|
icon: string;
|
|
app_type: string;
|
|
status: string;
|
|
model_name: string;
|
|
is_public: boolean;
|
|
conversation_count: number;
|
|
message_count: number;
|
|
sys_create_datetime?: string;
|
|
}
|
|
|
|
/** 创建应用 */
|
|
export interface AppCreateInput {
|
|
name: string;
|
|
code: string;
|
|
description?: string;
|
|
icon?: string;
|
|
app_type?: string;
|
|
model_id?: string;
|
|
system_prompt?: string;
|
|
temperature?: number;
|
|
top_p?: number;
|
|
max_tokens?: number;
|
|
opening_statement?: string;
|
|
suggested_questions?: string[];
|
|
workflow_definition?: Record<string, any>;
|
|
is_public?: boolean;
|
|
sort?: number;
|
|
}
|
|
|
|
/** 通用 AI 对话 */
|
|
export interface Conversation {
|
|
id: string;
|
|
app_id: string;
|
|
app_name: string;
|
|
title: string;
|
|
message_count: number;
|
|
total_tokens: number;
|
|
is_pinned: boolean;
|
|
sort?: number;
|
|
sys_create_datetime?: string;
|
|
sys_update_datetime?: string;
|
|
}
|
|
|
|
/** 通用 AI 对话列表项 */
|
|
export interface ConversationListItem {
|
|
id: string;
|
|
title: string;
|
|
message_count: number;
|
|
is_pinned: boolean;
|
|
sys_update_datetime?: string;
|
|
}
|
|
|
|
/** 通用 AI 消息 */
|
|
export interface Message {
|
|
id: string;
|
|
role: 'assistant' | 'system' | 'user';
|
|
content: string;
|
|
status: 'completed' | 'failed' | 'pending' | 'stopped';
|
|
prompt_tokens: number;
|
|
completion_tokens: number;
|
|
total_tokens: number;
|
|
model_name: string;
|
|
latency: number;
|
|
error_message: string;
|
|
feedback: string;
|
|
sys_create_datetime?: string;
|
|
}
|
|
|
|
export type WorkflowType = 'application' | 'automation' | 'data_process' | 'form' | 'general' | 'report';
|
|
|
|
/** AI 工作流 */
|
|
export interface AIWorkflow {
|
|
id: string;
|
|
name: string;
|
|
code: string;
|
|
workflow_type: WorkflowType;
|
|
description: string;
|
|
status: 'disabled' | 'draft' | 'published';
|
|
version: number;
|
|
published_version: null | number;
|
|
published_at: null | string;
|
|
published_definition: Record<string, any>;
|
|
definition: Record<string, any>;
|
|
input_variables: any[];
|
|
output_variables: any[];
|
|
run_count: number;
|
|
success_count: number;
|
|
created_at: string;
|
|
updated_at: string;
|
|
}
|
|
|
|
/** 工作流版本 */
|
|
export interface WorkflowVersion {
|
|
id: string;
|
|
version: number;
|
|
description: string;
|
|
definition?: Record<string, any>;
|
|
published_by: null | string;
|
|
published_at: string;
|
|
run_count: number;
|
|
success_count: number;
|
|
}
|
|
|
|
/** 工作流列表项 */
|
|
export interface WorkflowListItem {
|
|
id: string;
|
|
application_id?: string;
|
|
application_name?: string;
|
|
is_global?: boolean;
|
|
name: string;
|
|
code: string;
|
|
workflow_type: WorkflowType;
|
|
description: string;
|
|
status: string;
|
|
version: number;
|
|
published_version: null | number;
|
|
published_at: null | string;
|
|
run_count: number;
|
|
success_count: number;
|
|
sys_create_datetime: string;
|
|
}
|
|
|
|
/** 工作流运行记录 */
|
|
export interface ExecutionLogEntry {
|
|
node_id: string;
|
|
node_type: string;
|
|
node_label?: string;
|
|
status: string;
|
|
output?: any;
|
|
inputs?: Record<string, any>;
|
|
error?: string;
|
|
elapsed_time?: number;
|
|
tokens_used?: number;
|
|
}
|
|
|
|
export interface WorkflowRunListItem {
|
|
id: string;
|
|
workflow_id: string;
|
|
workflow_name: string;
|
|
status: string;
|
|
trigger_type: string;
|
|
total_steps: number;
|
|
total_tokens: number;
|
|
elapsed_time: number;
|
|
error_message: string;
|
|
started_at: string;
|
|
completed_at: string;
|
|
}
|
|
|
|
export interface WorkflowRun {
|
|
id: string;
|
|
workflow_id: string;
|
|
workflow_name: string;
|
|
status: string;
|
|
trigger_type: string;
|
|
use_draft: boolean;
|
|
workflow_version: null | number;
|
|
definition_snapshot: Record<string, any>;
|
|
inputs: Record<string, any>;
|
|
outputs: Record<string, any>;
|
|
execution_log: ExecutionLogEntry[];
|
|
current_node_id: string;
|
|
waiting_config: Record<string, any>;
|
|
error_message: string;
|
|
total_tokens: number;
|
|
total_steps: number;
|
|
elapsed_time: number;
|
|
started_at: string;
|
|
completed_at: string;
|
|
sys_create_datetime: string;
|
|
}
|
|
|
|
/** 节点 Schema */
|
|
export interface NodeSchema {
|
|
node_type: string;
|
|
node_name: string;
|
|
category: string;
|
|
icon: string;
|
|
description: string;
|
|
inputs: any[];
|
|
outputs: any[];
|
|
supports_branches: boolean;
|
|
}
|
|
|
|
/** 工作流详情(别名) */
|
|
export type WorkflowDetail = AIWorkflow;
|
|
|
|
/** 分页响应 */
|
|
interface PaginatedResponse<T> {
|
|
items: T[];
|
|
page: number;
|
|
pageSize: number;
|
|
total: number;
|
|
}
|
|
|
|
// ============ 提供商 API ============
|
|
|
|
/** 获取提供商类型列表 */
|
|
export async function getProviderTypesApi() {
|
|
return requestClient.get<ProviderType[]>(`${BASE_URL}/provider/types`);
|
|
}
|
|
|
|
/** 获取提供商列表 */
|
|
export async function getProviderListApi(params?: {
|
|
is_active?: boolean;
|
|
name?: string;
|
|
page?: number;
|
|
pageSize?: number;
|
|
provider_type?: string;
|
|
}) {
|
|
return requestClient.get<PaginatedResponse<ProviderListItem>>(
|
|
`${BASE_URL}/provider/list`,
|
|
{ params },
|
|
);
|
|
}
|
|
|
|
/** 获取提供商详情 */
|
|
export async function getProviderDetailApi(id: string) {
|
|
return requestClient.get<LLMProvider>(`${BASE_URL}/provider/${id}`);
|
|
}
|
|
|
|
/** 创建提供商 */
|
|
export async function createProviderApi(data: ProviderCreateInput) {
|
|
return requestClient.post<LLMProvider>(`${BASE_URL}/provider`, data);
|
|
}
|
|
|
|
/** 更新提供商 */
|
|
export async function updateProviderApi(
|
|
id: string,
|
|
data: Partial<ProviderCreateInput>,
|
|
) {
|
|
return requestClient.put<LLMProvider>(`${BASE_URL}/provider/${id}`, data);
|
|
}
|
|
|
|
/** 删除提供商 */
|
|
export async function deleteProviderApi(id: string) {
|
|
return requestClient.delete(`${BASE_URL}/provider/${id}`);
|
|
}
|
|
|
|
/** 测试提供商连接 */
|
|
export async function testProviderApi(id: string) {
|
|
return requestClient.post<{
|
|
message: string;
|
|
model_count: number;
|
|
models: DefaultModel[];
|
|
source: 'api';
|
|
success: boolean;
|
|
}>(`${BASE_URL}/provider/${id}/test`);
|
|
}
|
|
|
|
/** 获取提供商默认模型列表 */
|
|
export async function getProviderDefaultModelsApi(id: string) {
|
|
return requestClient.get<DefaultModel[]>(
|
|
`${BASE_URL}/provider/${id}/default-models`,
|
|
);
|
|
}
|
|
|
|
/** 在线拉取提供商最新模型列表(优先 API 拉取,失败 fallback 到默认列表) */
|
|
export async function fetchProviderModelsApi(id: string) {
|
|
return requestClient.get<{ models: DefaultModel[]; source: string }>(
|
|
`${BASE_URL}/provider/${id}/fetch-models`,
|
|
);
|
|
}
|
|
|
|
// ============ 模型 API ============
|
|
|
|
/** 获取模型列表 */
|
|
export async function getModelListApi(params?: {
|
|
is_active?: boolean;
|
|
model_type?: string;
|
|
page?: number;
|
|
pageSize?: number;
|
|
provider_id?: string;
|
|
}) {
|
|
return requestClient.get<PaginatedResponse<ModelListItem>>(
|
|
`${BASE_URL}/model/list`,
|
|
{ params },
|
|
);
|
|
}
|
|
|
|
/** 获取可用模型列表 */
|
|
export async function getActiveModelsApi() {
|
|
return requestClient.get<ModelListItem[]>(`${BASE_URL}/model/active`);
|
|
}
|
|
|
|
/** 获取模型详情 */
|
|
export async function getModelDetailApi(id: string) {
|
|
return requestClient.get<LLMModel>(`${BASE_URL}/model/${id}`);
|
|
}
|
|
|
|
/** 创建模型 */
|
|
export async function createModelApi(data: ModelCreateInput) {
|
|
return requestClient.post<LLMModel>(`${BASE_URL}/model`, data);
|
|
}
|
|
|
|
/** 批量创建模型 */
|
|
export async function batchCreateModelsApi(
|
|
providerId: string,
|
|
models: DefaultModel[],
|
|
) {
|
|
return requestClient.post<{ message: string }>(
|
|
`${BASE_URL}/model/batch`,
|
|
models,
|
|
{ params: { provider_id: providerId } },
|
|
);
|
|
}
|
|
|
|
/** 更新模型 */
|
|
export async function updateModelApi(
|
|
id: string,
|
|
data: Partial<ModelCreateInput>,
|
|
) {
|
|
return requestClient.put<LLMModel>(`${BASE_URL}/model/${id}`, data);
|
|
}
|
|
|
|
/** 删除模型 */
|
|
export async function deleteModelApi(id: string) {
|
|
return requestClient.delete(`${BASE_URL}/model/${id}`);
|
|
}
|
|
|
|
// ============ 应用 API ============
|
|
|
|
/** 获取应用列表 */
|
|
export async function getAppListApi(params?: {
|
|
app_type?: string;
|
|
name?: string;
|
|
page?: number;
|
|
pageSize?: number;
|
|
status?: string;
|
|
}) {
|
|
return requestClient.get<PaginatedResponse<AppListItem>>(
|
|
`${BASE_URL}/apps`,
|
|
{ params },
|
|
);
|
|
}
|
|
|
|
/** 获取已发布应用列表 */
|
|
export async function getPublishedAppsApi() {
|
|
return requestClient.get<AppListItem[]>(`${BASE_URL}/apps/published`);
|
|
}
|
|
|
|
/** 获取应用详情 */
|
|
export async function getAppDetailApi(id: string) {
|
|
return requestClient.get<AIApp>(`${BASE_URL}/apps/${id}`);
|
|
}
|
|
|
|
/** 根据编码获取应用 */
|
|
export async function getAppByCodeApi(code: string) {
|
|
return requestClient.get<AIApp>(`${BASE_URL}/apps/code/${code}`);
|
|
}
|
|
|
|
/** 创建应用 */
|
|
export async function createAppApi(data: AppCreateInput) {
|
|
return requestClient.post<AIApp>(`${BASE_URL}/apps`, data);
|
|
}
|
|
|
|
/** 更新应用 */
|
|
export async function updateAppApi(id: string, data: Partial<AppCreateInput>) {
|
|
return requestClient.put<AIApp>(`${BASE_URL}/apps/${id}`, data);
|
|
}
|
|
|
|
/** 删除应用 */
|
|
export async function deleteAppApi(id: string) {
|
|
return requestClient.delete(`${BASE_URL}/apps/${id}`);
|
|
}
|
|
|
|
/** 发布应用 */
|
|
export async function publishAppApi(id: string) {
|
|
return requestClient.post<AIApp>(`${BASE_URL}/apps/${id}/publish`);
|
|
}
|
|
|
|
/** 停用应用 */
|
|
export async function disableAppApi(id: string) {
|
|
return requestClient.post<AIApp>(`${BASE_URL}/apps/${id}/disable`);
|
|
}
|
|
|
|
// ============ 通用对话 API ============
|
|
|
|
/** 获取对话列表 */
|
|
export async function getConversationListApi(
|
|
appId: string,
|
|
params?: { page?: number; pageSize?: number },
|
|
) {
|
|
return requestClient.get<PaginatedResponse<ConversationListItem>>(
|
|
`${BASE_URL}/chat/conversations`,
|
|
{ params: { app_id: appId, ...params } },
|
|
);
|
|
}
|
|
|
|
/** 创建对话 */
|
|
export async function createConversationApi(data: {
|
|
app_id: string;
|
|
title?: string;
|
|
}) {
|
|
return requestClient.post<Conversation>(
|
|
`${BASE_URL}/chat/conversations`,
|
|
data,
|
|
);
|
|
}
|
|
|
|
/** 获取对话详情 */
|
|
export async function getConversationDetailApi(id: string) {
|
|
return requestClient.get<Conversation>(
|
|
`${BASE_URL}/chat/conversations/${id}`,
|
|
);
|
|
}
|
|
|
|
/** 更新对话 */
|
|
export async function updateConversationApi(
|
|
id: string,
|
|
data: { is_pinned?: boolean; title?: string },
|
|
) {
|
|
return requestClient.put<Conversation>(
|
|
`${BASE_URL}/chat/conversations/${id}`,
|
|
data,
|
|
);
|
|
}
|
|
|
|
/** 删除对话 */
|
|
export async function deleteConversationApi(id: string) {
|
|
return requestClient.delete(`${BASE_URL}/chat/conversations/${id}`);
|
|
}
|
|
|
|
/** 获取消息列表 */
|
|
export async function getMessagesApi(conversationId: string, limit?: number) {
|
|
return requestClient.get<Message[]>(
|
|
`${BASE_URL}/chat/conversations/${conversationId}/messages`,
|
|
{ params: { limit } },
|
|
);
|
|
}
|
|
|
|
/** 发送消息 */
|
|
export async function sendMessageApi(conversationId: string, content: string) {
|
|
return requestClient.post<Message>(
|
|
`${BASE_URL}/chat/conversations/${conversationId}/messages`,
|
|
{ content },
|
|
);
|
|
}
|
|
|
|
/** 聊天流式事件类型 */
|
|
export interface ChatStreamEvent {
|
|
type: 'content' | 'done' | 'error';
|
|
content?: string;
|
|
message?: {
|
|
content: string;
|
|
id: string;
|
|
latency: number;
|
|
tokens: number;
|
|
};
|
|
error?: string;
|
|
}
|
|
|
|
/** 流式发送消息 */
|
|
export function sendMessageStreamApi(
|
|
conversationId: string,
|
|
content: string,
|
|
onEvent: (event: ChatStreamEvent) => void,
|
|
onError?: (error: Error) => void,
|
|
onComplete?: () => void,
|
|
): () => void {
|
|
return streamRequestClient<ChatStreamEvent>(
|
|
`${BASE_URL}/chat/conversations/${conversationId}/messages/stream`,
|
|
{ content },
|
|
{
|
|
onData: onEvent,
|
|
onError: (error) => {
|
|
console.error('Stream error:', error);
|
|
onError?.(error);
|
|
},
|
|
onComplete,
|
|
},
|
|
);
|
|
}
|
|
|
|
/** 消息反馈 */
|
|
export async function messageFeedbackApi(
|
|
messageId: string,
|
|
feedback: 'dislike' | 'like' | '',
|
|
) {
|
|
return requestClient.post(`${BASE_URL}/chat/messages/${messageId}/feedback`, {
|
|
feedback,
|
|
});
|
|
}
|
|
|
|
/** 获取节点 Schema 列表 */
|
|
export async function getNodeSchemasApi() {
|
|
return requestClient.get<NodeSchema[]>(`${BASE_URL}/workflow/nodes/schemas`);
|
|
}
|
|
|
|
/** Snowflake 连接测试输入 */
|
|
export interface SnowflakeConnectionTestInput {
|
|
auth_type: 'externalbrowser' | 'key_pair' | 'password';
|
|
account: string;
|
|
user: string;
|
|
password?: string;
|
|
private_key?: string;
|
|
private_key_path?: string;
|
|
private_key_passphrase?: string;
|
|
warehouse: string;
|
|
database: string;
|
|
schema?: string;
|
|
role?: string;
|
|
}
|
|
|
|
/** Snowflake 连接测试结果 */
|
|
export interface SnowflakeConnectionTestResult {
|
|
success: boolean;
|
|
message: string;
|
|
elapsed_time: number;
|
|
details?: {
|
|
database: string;
|
|
schema: string;
|
|
version: string;
|
|
warehouse: string;
|
|
};
|
|
}
|
|
|
|
/** 测试 Snowflake 连接 */
|
|
export async function testSnowflakeConnectionApi(
|
|
data: SnowflakeConnectionTestInput,
|
|
) {
|
|
return requestClient.post<SnowflakeConnectionTestResult>(
|
|
`${BASE_URL}/workflow/snowflake/test-connection`,
|
|
data,
|
|
);
|
|
}
|
|
|
|
/** 按分类获取节点 Schema */
|
|
export async function getNodeSchemasByCategoryApi() {
|
|
return requestClient.get<Record<string, NodeSchema[]>>(
|
|
`${BASE_URL}/workflow/nodes/schemas/by-category`,
|
|
);
|
|
}
|
|
|
|
/** 获取工作流列表 */
|
|
export async function getWorkflowListApi(params?: {
|
|
applicationId?: string;
|
|
name?: string;
|
|
page?: number;
|
|
pageSize?: number;
|
|
status?: string;
|
|
workflow_type?: WorkflowType;
|
|
}) {
|
|
return requestClient.get<PaginatedResponse<WorkflowListItem>>(
|
|
`${BASE_URL}/workflow/list`,
|
|
{ params },
|
|
);
|
|
}
|
|
|
|
/** 获取工作流详情 */
|
|
export async function getWorkflowDetailApi(id: string) {
|
|
return requestClient.get<AIWorkflow>(`${BASE_URL}/workflow/${id}`);
|
|
}
|
|
|
|
/** 获取工作流详情(别名) */
|
|
export const getWorkflowApi = getWorkflowDetailApi;
|
|
|
|
/** 根据编码获取工作流 */
|
|
export async function getWorkflowByCodeApi(code: string) {
|
|
return requestClient.get<AIWorkflow>(`${BASE_URL}/workflow/code/${code}`);
|
|
}
|
|
|
|
/** 创建工作流 */
|
|
export async function createWorkflowApi(data: {
|
|
application_id?: string;
|
|
code: string;
|
|
definition?: Record<string, any>;
|
|
description?: string;
|
|
input_variables?: any[];
|
|
is_global?: boolean;
|
|
name: string;
|
|
output_variables?: any[];
|
|
workflow_type?: WorkflowType;
|
|
}) {
|
|
return requestClient.post<AIWorkflow>(`${BASE_URL}/workflow`, data);
|
|
}
|
|
|
|
/** 更新工作流 */
|
|
export async function updateWorkflowApi(
|
|
id: string,
|
|
data: Partial<{
|
|
code: string;
|
|
definition: Record<string, any>;
|
|
description: string;
|
|
input_variables: any[];
|
|
is_global: boolean;
|
|
name: string;
|
|
output_variables: any[];
|
|
workflow_type: WorkflowType;
|
|
}>,
|
|
) {
|
|
return requestClient.put<AIWorkflow>(`${BASE_URL}/workflow/${id}`, data);
|
|
}
|
|
|
|
/** 删除工作流 */
|
|
export async function deleteWorkflowApi(id: string) {
|
|
return requestClient.delete(`${BASE_URL}/workflow/${id}`);
|
|
}
|
|
|
|
/** 复制工作流 */
|
|
export async function copyWorkflowApi(id: string) {
|
|
return requestClient.post<AIWorkflow>(`${BASE_URL}/workflow/${id}/copy`);
|
|
}
|
|
|
|
/** 工作流导入请求 */
|
|
export interface WorkflowImportInput {
|
|
application_id?: string;
|
|
is_global?: boolean;
|
|
name: string;
|
|
code: string;
|
|
workflow_type?: WorkflowType;
|
|
description?: string;
|
|
definition?: Record<string, any>;
|
|
input_variables?: any[];
|
|
output_variables?: any[];
|
|
}
|
|
|
|
/** 工作流导入预检查请求 */
|
|
export interface WorkflowImportCheckInput {
|
|
code: string;
|
|
}
|
|
|
|
/** 工作流导入预检查结果 */
|
|
export interface WorkflowImportCheckResult {
|
|
code_exists: boolean;
|
|
can_import: boolean;
|
|
}
|
|
|
|
/** 导出工作流配置(返回 JSON 文件) */
|
|
export async function exportWorkflowConfigApi(workflowId: string) {
|
|
return requestClient.get<Blob>(`${BASE_URL}/workflow/${workflowId}/export`, {
|
|
responseType: 'blob',
|
|
});
|
|
}
|
|
|
|
/** 导入预检查 */
|
|
export async function checkImportWorkflowApi(data: WorkflowImportCheckInput) {
|
|
return requestClient.post<WorkflowImportCheckResult>(
|
|
`${BASE_URL}/workflow/import/check`,
|
|
data,
|
|
);
|
|
}
|
|
|
|
/** 导入工作流配置 */
|
|
export async function importWorkflowConfigApi(data: WorkflowImportInput) {
|
|
return requestClient.post<AIWorkflow>(`${BASE_URL}/workflow/import`, data);
|
|
}
|
|
|
|
/** 发布工作流 */
|
|
export async function publishWorkflowApi(id: string, description: string = '') {
|
|
return requestClient.post<AIWorkflow>(
|
|
`${BASE_URL}/workflow/${id}/publish`,
|
|
null,
|
|
{
|
|
params: { description },
|
|
},
|
|
);
|
|
}
|
|
|
|
/** 获取版本历史 */
|
|
export async function getWorkflowVersionsApi(
|
|
id: string,
|
|
params?: { page?: number; pageSize?: number },
|
|
) {
|
|
return requestClient.get<{
|
|
items: WorkflowVersion[];
|
|
page: number;
|
|
pageSize: number;
|
|
total: number;
|
|
}>(`${BASE_URL}/workflow/${id}/versions`, { params });
|
|
}
|
|
|
|
/** 获取指定版本 */
|
|
export async function getWorkflowVersionApi(id: string, version: number) {
|
|
return requestClient.get<WorkflowVersion>(
|
|
`${BASE_URL}/workflow/${id}/versions/${version}`,
|
|
);
|
|
}
|
|
|
|
/** 回滚到指定版本 */
|
|
export async function rollbackWorkflowApi(id: string, version: number) {
|
|
return requestClient.post<AIWorkflow>(
|
|
`${BASE_URL}/workflow/${id}/rollback`,
|
|
null,
|
|
{
|
|
params: { version },
|
|
},
|
|
);
|
|
}
|
|
|
|
/** 运行工作流 */
|
|
export async function runWorkflowApi(
|
|
id: string,
|
|
inputs: Record<string, any> = {},
|
|
) {
|
|
return requestClient.post<WorkflowRun>(`${BASE_URL}/workflow/${id}/run`, {
|
|
inputs,
|
|
});
|
|
}
|
|
|
|
/** 工作流流式事件类型 */
|
|
export interface WorkflowStreamEvent {
|
|
type:
|
|
| 'answer'
|
|
| 'complete'
|
|
| 'error'
|
|
| 'llm_chunk'
|
|
| 'loop_complete'
|
|
| 'loop_iteration_complete'
|
|
| 'loop_iteration_error'
|
|
| 'loop_iteration_start'
|
|
| 'loop_start'
|
|
| 'node_complete'
|
|
| 'node_event'
|
|
| 'node_start'
|
|
| 'parallel_complete'
|
|
| 'parallel_start'
|
|
| 'start'
|
|
| 'waiting_input';
|
|
config?: any;
|
|
content?: string;
|
|
run_id?: string;
|
|
workflow_id?: string;
|
|
node_id?: string;
|
|
node_type?: string;
|
|
node_label?: string;
|
|
status?: string;
|
|
elapsed_time?: number;
|
|
tokens_used?: number;
|
|
error_message?: string;
|
|
message?: string;
|
|
warnings?: string[];
|
|
outputs?: Record<string, any>;
|
|
total_tokens?: number;
|
|
timestamp?: string; // ISO 格式时间戳
|
|
inputs?: {
|
|
previous_output?: any;
|
|
variables?: Record<string, any>;
|
|
};
|
|
// LLM 流式输出字段
|
|
accumulated_content?: string; // 累积内容
|
|
// 并行执行字段
|
|
branches?: string[]; // 并行分支 ID 列表
|
|
branch_results?: Record<string, any>; // 各分支执行结果
|
|
// 循环迭代字段
|
|
iteration?: number; // 当前迭代次数(从 0 开始)
|
|
total?: number; // 总迭代次数(for_each 模式)
|
|
total_iterations?: number; // 循环完成时的总迭代次数
|
|
results_count?: number; // 循环结果数量
|
|
loop_iteration?: number; // 循环内子节点的迭代索引
|
|
item?: any; // 当前迭代项
|
|
output?: any; // 迭代输出
|
|
error?: string; // 错误信息
|
|
// 对话流节点字段
|
|
event?: {
|
|
content?: string;
|
|
message_type?: string;
|
|
type: string;
|
|
};
|
|
waiting_config?: {
|
|
cancel_text?: string;
|
|
confirm_text?: string;
|
|
content?: string;
|
|
default_value?: string;
|
|
input_type?: string;
|
|
max_select?: number;
|
|
min_select?: number;
|
|
multiple?: boolean;
|
|
options?: Array<{ label: string; value: string }>;
|
|
placeholder?: string;
|
|
question?: string;
|
|
required?: boolean;
|
|
title?: string;
|
|
type: string;
|
|
};
|
|
}
|
|
|
|
/** 流式运行工作流 */
|
|
export function runWorkflowStreamApi(
|
|
id: string,
|
|
inputs: Record<string, any> = {},
|
|
onEvent: (event: WorkflowStreamEvent) => void,
|
|
onError?: (error: Error) => void,
|
|
onComplete?: () => void,
|
|
useDraft: boolean = false,
|
|
): () => void {
|
|
return streamRequestClient<WorkflowStreamEvent>(
|
|
`${BASE_URL}/workflow/${id}/run/stream`,
|
|
{ inputs, use_draft: useDraft },
|
|
{
|
|
onData: onEvent,
|
|
onError: (error) => {
|
|
console.error('Workflow stream error:', error);
|
|
onError?.(error);
|
|
},
|
|
onComplete,
|
|
},
|
|
);
|
|
}
|
|
|
|
/** 获取工作流运行记录 */
|
|
export async function getWorkflowRunsApi(
|
|
workflowId: string,
|
|
params?: { page?: number; pageSize?: number },
|
|
) {
|
|
return requestClient.get<PaginatedResponse<WorkflowRunListItem>>(
|
|
`${BASE_URL}/workflow/${workflowId}/runs`,
|
|
{ params },
|
|
);
|
|
}
|
|
|
|
/** 获取全局工作流运行记录 */
|
|
export async function getAllWorkflowRunsApi(params?: {
|
|
applicationId?: string;
|
|
page?: number;
|
|
pageSize?: number;
|
|
workflowId?: string;
|
|
status?: string;
|
|
triggerType?: string;
|
|
}) {
|
|
return requestClient.get<PaginatedResponse<WorkflowRunListItem>>(
|
|
`${BASE_URL}/workflow/runs`,
|
|
{ params },
|
|
);
|
|
}
|
|
|
|
/** 获取运行记录详情 */
|
|
export async function getWorkflowRunDetailApi(runId: string) {
|
|
return requestClient.get<WorkflowRun>(`${BASE_URL}/workflow/runs/${runId}`);
|
|
}
|
|
|
|
/** 停止工作流运行 */
|
|
export async function stopWorkflowRunApi(runId: string) {
|
|
return requestClient.post(`${BASE_URL}/workflow/runs/${runId}/stop`);
|
|
}
|
|
|
|
/** 恢复工作流执行(流式) */
|
|
export function resumeWorkflowStreamApi(
|
|
runId: string,
|
|
userInput: any,
|
|
onEvent: (event: WorkflowStreamEvent) => void,
|
|
onError?: (error: Error) => void,
|
|
onComplete?: () => void,
|
|
): () => void {
|
|
return streamRequestClient<WorkflowStreamEvent>(
|
|
`${BASE_URL}/workflow/runs/${runId}/resume/stream`,
|
|
{ user_input: userInput },
|
|
{
|
|
onData: onEvent,
|
|
onError: (error) => {
|
|
console.error('Resume workflow stream error:', error);
|
|
onError?.(error);
|
|
},
|
|
onComplete,
|
|
},
|
|
);
|
|
}
|
|
|
|
// ============ 智能体 API ============
|
|
|
|
/** 人设配置 */
|
|
export interface PersonaConfig {
|
|
role?: string;
|
|
personality?: string[];
|
|
skills?: string[];
|
|
constraints?: string[];
|
|
background?: string;
|
|
examples?: Array<{ assistant: string; user: string }>;
|
|
}
|
|
|
|
/** 智能体 */
|
|
export interface Agent {
|
|
id: string;
|
|
name: string;
|
|
code: string;
|
|
description: string;
|
|
avatar: string;
|
|
mode: 'autonomous' | 'dialog_flow';
|
|
status: 'disabled' | 'draft' | 'published';
|
|
persona: PersonaConfig;
|
|
system_prompt: string;
|
|
model_id: null | string;
|
|
model_name: string;
|
|
temperature: number;
|
|
top_p: number;
|
|
max_tokens: number;
|
|
max_iterations: number;
|
|
welcome_message: string;
|
|
suggested_questions: string[];
|
|
workflow_id: null | string;
|
|
workflow_name: string;
|
|
workflow_type: WorkflowType;
|
|
is_public: boolean;
|
|
enable_memory: boolean;
|
|
memory_window: number;
|
|
enable_streaming: boolean;
|
|
knowledge_base_ids: string[];
|
|
knowledge_config: Record<string, any>;
|
|
conversation_count: number;
|
|
message_count: number;
|
|
total_tokens: number;
|
|
created_at: string;
|
|
updated_at: string;
|
|
}
|
|
|
|
/** 智能体列表项 */
|
|
export interface AgentListItem {
|
|
id: string;
|
|
application_id?: string;
|
|
application_name?: string;
|
|
is_global?: boolean;
|
|
name: string;
|
|
code: string;
|
|
description: string;
|
|
avatar: string;
|
|
mode: string;
|
|
status: string;
|
|
model_name: string;
|
|
workflow_name?: string;
|
|
is_public: boolean;
|
|
conversation_count: number;
|
|
message_count: number;
|
|
has_menu?: boolean;
|
|
sys_create_datetime: string;
|
|
}
|
|
|
|
/** 创建智能体 */
|
|
export interface AgentCreateInput {
|
|
application_id?: string;
|
|
is_global?: boolean;
|
|
name: string;
|
|
code: string;
|
|
description?: string;
|
|
avatar?: string;
|
|
mode?: 'autonomous' | 'dialog_flow';
|
|
persona?: PersonaConfig;
|
|
system_prompt?: string;
|
|
model_id?: string;
|
|
temperature?: number;
|
|
top_p?: number;
|
|
max_tokens?: number;
|
|
max_iterations?: number;
|
|
welcome_message?: string;
|
|
suggested_questions?: string[];
|
|
workflow_id?: string;
|
|
knowledge_base_ids?: string[];
|
|
knowledge_config?: Record<string, any>;
|
|
is_public?: boolean;
|
|
}
|
|
|
|
/** 更新智能体 */
|
|
export interface AgentUpdateInput {
|
|
application_id?: string;
|
|
is_global?: boolean;
|
|
name?: string;
|
|
description?: string;
|
|
avatar?: string;
|
|
mode?: 'autonomous' | 'dialog_flow';
|
|
persona?: PersonaConfig;
|
|
system_prompt?: string;
|
|
model_id?: string;
|
|
temperature?: number;
|
|
top_p?: number;
|
|
max_tokens?: number;
|
|
max_iterations?: number;
|
|
welcome_message?: string;
|
|
suggested_questions?: string[];
|
|
workflow_id?: string;
|
|
knowledge_base_ids?: string[];
|
|
knowledge_config?: Record<string, any>;
|
|
is_public?: boolean;
|
|
enable_memory?: boolean;
|
|
memory_window?: number;
|
|
enable_streaming?: boolean;
|
|
}
|
|
|
|
/** 智能体对话 */
|
|
export interface AgentConversation {
|
|
id: string;
|
|
agent_id: string;
|
|
agent_name: string;
|
|
title: string;
|
|
summary?: string;
|
|
message_count: number;
|
|
total_tokens?: number;
|
|
created_at?: string;
|
|
updated_at?: string;
|
|
sys_create_datetime?: string;
|
|
}
|
|
|
|
/** 推理步骤 */
|
|
export interface ReasoningStep {
|
|
type:
|
|
| 'action'
|
|
| 'annotation_reply'
|
|
| 'knowledge_retrieval'
|
|
| 'node_complete'
|
|
| 'node_start'
|
|
| 'observation'
|
|
| 'thought';
|
|
content: string;
|
|
tool?: string;
|
|
params?: Record<string, any>;
|
|
timestamp: string;
|
|
// 对话流模式:节点信息
|
|
node_id?: string;
|
|
node_type?: string;
|
|
output?: any;
|
|
/** 步骤状态:running 执行中,completed 已完成 */
|
|
status?: 'completed' | 'running';
|
|
}
|
|
|
|
/** 工具调用记录 */
|
|
export interface ToolCallRecord {
|
|
tool: string;
|
|
params: Record<string, any>;
|
|
result: any;
|
|
elapsed_time: number;
|
|
status: string;
|
|
}
|
|
|
|
/** 智能体消息 */
|
|
export interface AgentMessage {
|
|
id: string;
|
|
role: 'assistant' | 'system' | 'tool' | 'user';
|
|
content: string;
|
|
status: 'completed' | 'failed' | 'pending';
|
|
reasoning_steps: ReasoningStep[];
|
|
tool_calls: ToolCallRecord[];
|
|
prompt_tokens: number;
|
|
completion_tokens: number;
|
|
total_tokens: number;
|
|
elapsed_time: number;
|
|
error_message: string;
|
|
feedback: string;
|
|
created_at: string;
|
|
sys_create_datetime?: string;
|
|
interaction?: WaitingInputConfig;
|
|
voice?: {
|
|
audioUrl?: string;
|
|
duration?: number;
|
|
transcribedText?: string;
|
|
transcribeStatus?: 'completed' | 'failed' | 'transcribing';
|
|
};
|
|
}
|
|
|
|
/** 等待输入配置 */
|
|
export interface WaitingInputConfig {
|
|
type: 'choice' | 'confirm' | 'question';
|
|
question?: string;
|
|
input_type?: string;
|
|
placeholder?: string;
|
|
default_value?: string;
|
|
required?: boolean;
|
|
error_message?: string;
|
|
options?: Array<{ description?: string; label: string; value: string }>;
|
|
multiple?: boolean;
|
|
min_select?: number;
|
|
max_select?: number;
|
|
title?: string;
|
|
content?: string;
|
|
confirm_text?: string;
|
|
cancel_text?: string;
|
|
}
|
|
|
|
/** 对话流式事件 */
|
|
export interface AgentChatEvent {
|
|
type:
|
|
| 'action'
|
|
| 'annotation_reply'
|
|
| 'answer'
|
|
| 'complete'
|
|
| 'error'
|
|
| 'knowledge_retrieval'
|
|
| 'llm_chunk'
|
|
| 'node_complete'
|
|
| 'node_event'
|
|
| 'node_start'
|
|
| 'observation'
|
|
| 'start'
|
|
| 'thought'
|
|
| 'waiting_input';
|
|
content?: string;
|
|
tool?: string;
|
|
params?: Record<string, any>;
|
|
message_id?: string;
|
|
conversation_id?: string;
|
|
tokens_used?: number;
|
|
total_tokens?: number;
|
|
elapsed_time?: number;
|
|
config?: WaitingInputConfig;
|
|
accumulated_content?: string;
|
|
// 对话流模式:节点执行事件
|
|
node_id?: string;
|
|
node_type?: string;
|
|
node_label?: string;
|
|
output?: any;
|
|
outputs?: {
|
|
output?: any;
|
|
output_variables?: Record<string, any>;
|
|
};
|
|
// node_event 事件
|
|
event?: {
|
|
content?: string;
|
|
type?: string;
|
|
};
|
|
}
|
|
|
|
// ============ 智能体 API ============
|
|
|
|
/** 获取智能体列表 */
|
|
export async function getAgentListApi(params?: {
|
|
applicationId?: string;
|
|
mode?: string;
|
|
name?: string;
|
|
page?: number;
|
|
pageSize?: number;
|
|
status?: string;
|
|
}) {
|
|
return requestClient.get<PaginatedResponse<AgentListItem>>(
|
|
`${BASE_URL}/agent/list`,
|
|
{ params },
|
|
);
|
|
}
|
|
|
|
/** 获取已发布智能体列表 */
|
|
export async function getPublishedAgentsApi() {
|
|
return requestClient.get<AgentListItem[]>(`${BASE_URL}/agent/published`);
|
|
}
|
|
|
|
/** 获取智能体详情 */
|
|
export async function getAgentDetailApi(agentId: string) {
|
|
return requestClient.get<Agent>(`${BASE_URL}/agent/${agentId}`);
|
|
}
|
|
|
|
/** 根据编码获取智能体 */
|
|
export async function getAgentByCodeApi(code: string) {
|
|
return requestClient.get<Agent>(`${BASE_URL}/agent/code/${code}`);
|
|
}
|
|
|
|
/** 创建智能体 */
|
|
export async function createAgentApi(data: AgentCreateInput) {
|
|
return requestClient.post<Agent>(`${BASE_URL}/agent`, data);
|
|
}
|
|
|
|
/** 更新智能体 */
|
|
export async function updateAgentApi(agentId: string, data: AgentUpdateInput) {
|
|
return requestClient.put<Agent>(`${BASE_URL}/agent/${agentId}`, data);
|
|
}
|
|
|
|
/** 删除智能体 */
|
|
export async function deleteAgentApi(agentId: string) {
|
|
return requestClient.delete(`${BASE_URL}/agent/${agentId}`);
|
|
}
|
|
|
|
/** 智能体导入请求 */
|
|
export interface AgentImportInput {
|
|
application_id?: string;
|
|
is_global?: boolean;
|
|
name: string;
|
|
code: string;
|
|
description?: string;
|
|
avatar?: string;
|
|
mode?: string;
|
|
persona?: Record<string, any>;
|
|
system_prompt?: string;
|
|
model_name?: string;
|
|
temperature?: number;
|
|
top_p?: number;
|
|
max_tokens?: number;
|
|
max_iterations?: number;
|
|
welcome_message?: string;
|
|
suggested_questions?: string[];
|
|
workflow_code?: string;
|
|
knowledge_base_codes?: string[];
|
|
knowledge_config?: Record<string, any>;
|
|
enable_memory?: boolean;
|
|
memory_window?: number;
|
|
enable_streaming?: boolean;
|
|
is_public?: boolean;
|
|
}
|
|
|
|
/** 智能体导入预检查请求 */
|
|
export interface AgentImportCheckInput {
|
|
code: string;
|
|
}
|
|
|
|
/** 智能体导入预检查结果 */
|
|
export interface AgentImportCheckResult {
|
|
code_exists: boolean;
|
|
can_import: boolean;
|
|
}
|
|
|
|
/** 导出智能体配置(返回 JSON 文件) */
|
|
export async function exportAgentConfigApi(agentId: string) {
|
|
return requestClient.get<Blob>(`${BASE_URL}/agent/${agentId}/export`, {
|
|
responseType: 'blob',
|
|
});
|
|
}
|
|
|
|
/** 导入预检查 */
|
|
export async function checkImportAgentApi(data: AgentImportCheckInput) {
|
|
return requestClient.post<AgentImportCheckResult>(
|
|
`${BASE_URL}/agent/import/check`,
|
|
data,
|
|
);
|
|
}
|
|
|
|
/** 导入智能体配置 */
|
|
export async function importAgentConfigApi(data: AgentImportInput) {
|
|
return requestClient.post<Agent>(`${BASE_URL}/agent/import`, data);
|
|
}
|
|
|
|
/** 发布智能体 */
|
|
export async function publishAgentApi(agentId: string) {
|
|
return requestClient.post<Agent>(`${BASE_URL}/agent/${agentId}/publish`);
|
|
}
|
|
|
|
/** 发布智能体到菜单 */
|
|
export interface AgentPublishToMenuInput {
|
|
menu_name: string;
|
|
menu_parent_id?: string;
|
|
menu_icon?: string;
|
|
menu_order?: number;
|
|
}
|
|
|
|
export async function publishAgentToMenuApi(
|
|
agentId: string,
|
|
data: AgentPublishToMenuInput,
|
|
) {
|
|
return requestClient.post<Agent>(
|
|
`${BASE_URL}/agent/${agentId}/publish-to-menu`,
|
|
data,
|
|
);
|
|
}
|
|
|
|
/** 取消发布智能体菜单 */
|
|
export async function unpublishAgentMenuApi(agentId: string) {
|
|
return requestClient.post<Agent>(
|
|
`${BASE_URL}/agent/${agentId}/unpublish-menu`,
|
|
);
|
|
}
|
|
|
|
/** 停用智能体 */
|
|
export async function disableAgentApi(agentId: string) {
|
|
return requestClient.post<Agent>(`${BASE_URL}/agent/${agentId}/disable`);
|
|
}
|
|
|
|
// ============ 智能体对话 API ============
|
|
|
|
/** 获取对话列表 */
|
|
export async function getAgentConversationsApi(
|
|
agentId: string,
|
|
params?: { page?: number; pageSize?: number },
|
|
) {
|
|
return requestClient.get<PaginatedResponse<AgentConversation>>(
|
|
`${BASE_URL}/agent/${agentId}/conversations`,
|
|
{ params },
|
|
);
|
|
}
|
|
|
|
/** 创建对话 */
|
|
export async function createAgentConversationApi(
|
|
agentId: string,
|
|
data?: { title?: string },
|
|
) {
|
|
return requestClient.post<AgentConversation>(
|
|
`${BASE_URL}/agent/${agentId}/conversations`,
|
|
data,
|
|
);
|
|
}
|
|
|
|
/** 获取对话详情 */
|
|
export async function getAgentConversationDetailApi(conversationId: string) {
|
|
return requestClient.get<AgentConversation>(
|
|
`${BASE_URL}/agent/conversations/${conversationId}`,
|
|
);
|
|
}
|
|
|
|
/** 删除对话 */
|
|
export async function deleteAgentConversationApi(conversationId: string) {
|
|
return requestClient.delete(
|
|
`${BASE_URL}/agent/conversations/${conversationId}`,
|
|
);
|
|
}
|
|
|
|
/** 获取消息列表 */
|
|
export async function getAgentMessagesApi(
|
|
conversationId: string,
|
|
params?: { page?: number; pageSize?: number },
|
|
) {
|
|
return requestClient.get<AgentMessage[] | PaginatedResponse<AgentMessage>>(
|
|
`${BASE_URL}/agent/conversations/${conversationId}/messages`,
|
|
{ params },
|
|
);
|
|
}
|
|
|
|
/** 附件输入类型 - 通过 file_id 关联文件管理系统 */
|
|
export interface AttachmentInput {
|
|
file_id: string;
|
|
type: 'audio' | 'file' | 'image' | 'video';
|
|
}
|
|
|
|
/** 发送消息(流式) */
|
|
export function sendAgentMessageStream(
|
|
agentId: string,
|
|
data: {
|
|
attachments?: AttachmentInput[];
|
|
conversation_id?: string;
|
|
message: string;
|
|
},
|
|
onEvent: (event: AgentChatEvent) => void,
|
|
onError?: (error: Error) => void,
|
|
onComplete?: () => void,
|
|
) {
|
|
return streamRequestClient<AgentChatEvent>(
|
|
`${BASE_URL}/agent/${agentId}/chat`,
|
|
data,
|
|
{
|
|
onData: onEvent,
|
|
onError: (error) => {
|
|
console.error('Agent chat stream error:', error);
|
|
onError?.(error);
|
|
},
|
|
onComplete,
|
|
},
|
|
);
|
|
}
|
|
|
|
/** 消息反馈 */
|
|
export async function feedbackAgentMessageApi(
|
|
messageId: string,
|
|
data: { content?: string; feedback: 'dislike' | 'like' },
|
|
) {
|
|
return requestClient.post(
|
|
`${BASE_URL}/agent/message/${messageId}/feedback`,
|
|
data,
|
|
);
|
|
}
|
|
|
|
// ============ 语音识别 API ============
|
|
|
|
/** 语音识别结果 */
|
|
export interface TranscribeResult {
|
|
text: string;
|
|
duration: number;
|
|
}
|
|
|
|
/** 语音转文字 */
|
|
export async function transcribeAudioApi(
|
|
audioFile: Blob | File,
|
|
options?: {
|
|
language?: string;
|
|
provider?: 'dashscope' | 'openai';
|
|
},
|
|
) {
|
|
const formData = new FormData();
|
|
formData.append('audio', audioFile, 'audio.webm');
|
|
if (options?.language) {
|
|
formData.append('language', options.language);
|
|
}
|
|
if (options?.provider) {
|
|
formData.append('provider', options.provider);
|
|
}
|
|
|
|
return requestClient.post<TranscribeResult>(
|
|
`${BASE_URL}/speech/transcribe`,
|
|
formData,
|
|
{
|
|
headers: {
|
|
'Content-Type': 'multipart/form-data',
|
|
},
|
|
timeout: 60_000,
|
|
},
|
|
);
|
|
}
|
|
|
|
/** 文字转语音 */
|
|
export async function textToSpeechApi(
|
|
text: string,
|
|
options?: {
|
|
provider?: 'dashscope' | 'openai';
|
|
voice?: string;
|
|
},
|
|
): Promise<Blob> {
|
|
const params = new URLSearchParams();
|
|
params.append('text', text);
|
|
if (options?.voice) {
|
|
params.append('voice', options.voice);
|
|
}
|
|
if (options?.provider) {
|
|
params.append('provider', options.provider);
|
|
}
|
|
|
|
const response = await requestClient.post(
|
|
`${BASE_URL}/speech/tts?${params.toString()}`,
|
|
null,
|
|
{
|
|
responseType: 'blob',
|
|
},
|
|
);
|
|
|
|
return response as unknown as Blob;
|
|
}
|
|
|
|
// ============ 知识库 API ============
|
|
|
|
/** 知识库 */
|
|
export interface KnowledgeBase {
|
|
id: string;
|
|
application_id?: string;
|
|
is_global?: boolean;
|
|
name: string;
|
|
code: string;
|
|
description: string;
|
|
icon: string;
|
|
embedding_model_id?: string;
|
|
embedding_model_name: string;
|
|
embedding_dimensions: number;
|
|
chunk_strategy: string;
|
|
chunk_size: number;
|
|
chunk_overlap: number;
|
|
separator?: string;
|
|
retrieval_mode: string;
|
|
top_k: number;
|
|
score_threshold: number;
|
|
rerank_enabled: boolean;
|
|
rerank_model_id?: string;
|
|
retrieval_weight: number;
|
|
process_rules?: Record<string, any>;
|
|
indexing_technique: string;
|
|
document_count: number;
|
|
segment_count: number;
|
|
total_token_count: number;
|
|
total_char_count: number;
|
|
status: string;
|
|
sort: number;
|
|
sys_create_datetime?: string;
|
|
sys_update_datetime?: string;
|
|
}
|
|
|
|
/** 知识库列表项 */
|
|
export interface KnowledgeBaseListItem {
|
|
id: string;
|
|
application_id?: string;
|
|
application_name?: string;
|
|
is_global?: boolean;
|
|
name: string;
|
|
code: string;
|
|
description: string;
|
|
icon: string;
|
|
embedding_model_name: string;
|
|
document_count: number;
|
|
segment_count: number;
|
|
status: string;
|
|
sys_create_datetime?: string;
|
|
}
|
|
|
|
/** 创建知识库 */
|
|
export interface KnowledgeBaseCreateInput {
|
|
application_id?: string;
|
|
is_global?: boolean;
|
|
name: string;
|
|
code: string;
|
|
description?: string;
|
|
icon?: string;
|
|
embedding_model_id?: string;
|
|
embedding_dimensions?: number;
|
|
chunk_strategy?: string;
|
|
chunk_size?: number;
|
|
chunk_overlap?: number;
|
|
separator?: string;
|
|
retrieval_mode?: string;
|
|
top_k?: number;
|
|
score_threshold?: number;
|
|
rerank_enabled?: boolean;
|
|
rerank_model_id?: string;
|
|
retrieval_weight?: number;
|
|
process_rules?: Record<string, any>;
|
|
indexing_technique?: string;
|
|
}
|
|
|
|
/** 更新知识库 */
|
|
export interface KnowledgeBaseUpdateInput {
|
|
name?: string;
|
|
description?: string;
|
|
icon?: string;
|
|
embedding_model_id?: string;
|
|
embedding_dimensions?: number;
|
|
chunk_strategy?: string;
|
|
chunk_size?: number;
|
|
chunk_overlap?: number;
|
|
separator?: string;
|
|
retrieval_mode?: string;
|
|
top_k?: number;
|
|
score_threshold?: number;
|
|
rerank_enabled?: boolean;
|
|
rerank_model_id?: string;
|
|
retrieval_weight?: number;
|
|
process_rules?: Record<string, any>;
|
|
indexing_technique?: string;
|
|
status?: string;
|
|
is_global?: boolean;
|
|
}
|
|
|
|
/** 知识库文档 */
|
|
export interface KnowledgeDocument {
|
|
id: string;
|
|
knowledge_base_id: string;
|
|
file_id?: string;
|
|
name: string;
|
|
file_type: string;
|
|
file_size: number;
|
|
content_hash: string;
|
|
segment_count: number;
|
|
token_count: number;
|
|
char_count: number;
|
|
status: string;
|
|
error_message: string;
|
|
duplicate_warning?: string;
|
|
enabled: boolean;
|
|
indexing_started_at?: string;
|
|
indexing_completed_at?: string;
|
|
sys_create_datetime?: string;
|
|
sys_update_datetime?: string;
|
|
}
|
|
|
|
/** 文档列表项 */
|
|
export interface KnowledgeDocumentListItem {
|
|
id: string;
|
|
knowledge_base_id: string;
|
|
file_id?: string;
|
|
name: string;
|
|
file_type: string;
|
|
file_size: number;
|
|
segment_count: number;
|
|
token_count: number;
|
|
status: string;
|
|
duplicate_warning?: string;
|
|
enabled: boolean;
|
|
sys_create_datetime?: string;
|
|
}
|
|
|
|
/** 知识库分段 */
|
|
export interface KnowledgeSegment {
|
|
id: string;
|
|
document_id: string;
|
|
document_name: string;
|
|
position: number;
|
|
content: string;
|
|
answer?: string;
|
|
token_count: number;
|
|
char_count: number;
|
|
word_count?: number;
|
|
page_number?: number;
|
|
keywords?: string[];
|
|
extra_metadata?: Record<string, any>;
|
|
enabled: boolean;
|
|
hit_count: number;
|
|
embedding_status: string;
|
|
sys_create_datetime?: string;
|
|
}
|
|
|
|
/** 检索结果 */
|
|
export interface KnowledgeRetrievalResult {
|
|
segment_id: string;
|
|
document_id: string;
|
|
document_name: string;
|
|
knowledge_base_id: string;
|
|
knowledge_base_name: string;
|
|
content: string;
|
|
score: number;
|
|
token_count: number;
|
|
metadata?: Record<string, any>;
|
|
keywords?: string[];
|
|
match_source?: 'annotation' | 'fulltext' | 'vector';
|
|
parent_content?: string;
|
|
}
|
|
|
|
/** 分块预览项 */
|
|
export interface ChunkPreviewItem {
|
|
position: number;
|
|
content: string;
|
|
char_count: number;
|
|
token_count: number;
|
|
word_count: number;
|
|
answer?: string;
|
|
metadata?: Record<string, any>;
|
|
}
|
|
|
|
/** 分块预览响应 */
|
|
export interface ChunkPreviewResponse {
|
|
chunks: ChunkPreviewItem[];
|
|
total: number;
|
|
strategy: string;
|
|
chunk_size: number;
|
|
chunk_overlap: number;
|
|
}
|
|
|
|
/** 检索响应 */
|
|
export interface KnowledgeRetrievalResponse {
|
|
results: KnowledgeRetrievalResult[];
|
|
total: number;
|
|
query: string;
|
|
elapsed_time: number;
|
|
retrieval_mode: string;
|
|
rerank_applied: boolean;
|
|
}
|
|
|
|
/** 知识库简单列表项 */
|
|
export interface KnowledgeBaseSimpleItem {
|
|
id: string;
|
|
name: string;
|
|
code: string;
|
|
document_count: number;
|
|
segment_count: number;
|
|
}
|
|
|
|
/** 获取知识库列表 */
|
|
export async function getKnowledgeBaseListApi(params?: {
|
|
applicationId?: string;
|
|
name?: string;
|
|
page?: number;
|
|
pageSize?: number;
|
|
status?: string;
|
|
}) {
|
|
return requestClient.get<PaginatedResponse<KnowledgeBaseListItem>>(
|
|
`${BASE_URL}/knowledge/list`,
|
|
{ params },
|
|
);
|
|
}
|
|
|
|
/** 获取知识库简单列表(下拉选择用) */
|
|
export async function getKnowledgeBaseSimpleListApi(applicationId?: string) {
|
|
return requestClient.get<KnowledgeBaseSimpleItem[]>(
|
|
`${BASE_URL}/knowledge/simple`,
|
|
{ params: { applicationId } },
|
|
);
|
|
}
|
|
|
|
/** 获取知识库详情 */
|
|
export async function getKnowledgeBaseDetailApi(id: string) {
|
|
return requestClient.get<KnowledgeBase>(`${BASE_URL}/knowledge/${id}`);
|
|
}
|
|
|
|
/** 创建知识库 */
|
|
export async function createKnowledgeBaseApi(data: KnowledgeBaseCreateInput) {
|
|
return requestClient.post<KnowledgeBase>(`${BASE_URL}/knowledge`, data);
|
|
}
|
|
|
|
/** 更新知识库 */
|
|
export async function updateKnowledgeBaseApi(
|
|
id: string,
|
|
data: KnowledgeBaseUpdateInput,
|
|
) {
|
|
return requestClient.put<KnowledgeBase>(`${BASE_URL}/knowledge/${id}`, data);
|
|
}
|
|
|
|
/** 删除知识库 */
|
|
export async function deleteKnowledgeBaseApi(id: string) {
|
|
return requestClient.delete(`${BASE_URL}/knowledge/${id}`);
|
|
}
|
|
|
|
/** 获取文档列表 */
|
|
export async function getKnowledgeDocumentListApi(
|
|
kbId: string,
|
|
params?: {
|
|
name?: string;
|
|
page?: number;
|
|
pageSize?: number;
|
|
status?: string;
|
|
},
|
|
) {
|
|
return requestClient.get<PaginatedResponse<KnowledgeDocumentListItem>>(
|
|
`${BASE_URL}/knowledge/${kbId}/documents`,
|
|
{ params },
|
|
);
|
|
}
|
|
|
|
/** 添加文档 */
|
|
export async function addKnowledgeDocumentApi(
|
|
kbId: string,
|
|
data: { file_id: string; name?: string },
|
|
) {
|
|
return requestClient.post<KnowledgeDocument>(
|
|
`${BASE_URL}/knowledge/${kbId}/documents`,
|
|
data,
|
|
);
|
|
}
|
|
|
|
/** 批量添加文档 */
|
|
export async function batchAddKnowledgeDocumentsApi(
|
|
kbId: string,
|
|
fileIds: string[],
|
|
) {
|
|
return requestClient.post(`${BASE_URL}/knowledge/${kbId}/documents/batch`, {
|
|
file_ids: fileIds,
|
|
});
|
|
}
|
|
|
|
/** 获取文档详情 */
|
|
export async function getKnowledgeDocumentDetailApi(
|
|
kbId: string,
|
|
docId: string,
|
|
) {
|
|
return requestClient.get<KnowledgeDocument>(
|
|
`${BASE_URL}/knowledge/${kbId}/documents/${docId}`,
|
|
);
|
|
}
|
|
|
|
/** 删除文档 */
|
|
export async function deleteKnowledgeDocumentApi(kbId: string, docId: string) {
|
|
return requestClient.delete(
|
|
`${BASE_URL}/knowledge/${kbId}/documents/${docId}`,
|
|
);
|
|
}
|
|
|
|
/** 重新索引文档 */
|
|
export async function reindexKnowledgeDocumentApi(kbId: string, docId: string) {
|
|
return requestClient.post(
|
|
`${BASE_URL}/knowledge/${kbId}/documents/${docId}/reindex`,
|
|
);
|
|
}
|
|
|
|
/** 启用/禁用文档 */
|
|
export async function toggleKnowledgeDocumentApi(
|
|
kbId: string,
|
|
docId: string,
|
|
enabled: boolean,
|
|
) {
|
|
return requestClient.put<KnowledgeDocument>(
|
|
`${BASE_URL}/knowledge/${kbId}/documents/${docId}/toggle`,
|
|
null,
|
|
{ params: { enabled } },
|
|
);
|
|
}
|
|
|
|
/** 获取知识库分段列表 */
|
|
export async function getKnowledgeSegmentListApi(
|
|
kbId: string,
|
|
params?: {
|
|
embeddingStatus?: string;
|
|
enabled?: boolean;
|
|
keyword?: string;
|
|
metadataKey?: string;
|
|
metadataValue?: string;
|
|
page?: number;
|
|
pageSize?: number;
|
|
},
|
|
) {
|
|
return requestClient.get<PaginatedResponse<KnowledgeSegment>>(
|
|
`${BASE_URL}/knowledge/${kbId}/segments`,
|
|
{ params },
|
|
);
|
|
}
|
|
|
|
/** 获取文档分段列表 */
|
|
export async function getDocumentSegmentListApi(
|
|
kbId: string,
|
|
docId: string,
|
|
params?: {
|
|
keyword?: string;
|
|
page?: number;
|
|
pageSize?: number;
|
|
},
|
|
) {
|
|
return requestClient.get<PaginatedResponse<KnowledgeSegment>>(
|
|
`${BASE_URL}/knowledge/${kbId}/documents/${docId}/segments`,
|
|
{ params },
|
|
);
|
|
}
|
|
|
|
/** 更新分段 */
|
|
export async function updateKnowledgeSegmentApi(
|
|
kbId: string,
|
|
segmentId: string,
|
|
data: {
|
|
content?: string;
|
|
enabled?: boolean;
|
|
extra_metadata?: Record<string, any>;
|
|
keywords?: string[];
|
|
},
|
|
) {
|
|
return requestClient.put<KnowledgeSegment>(
|
|
`${BASE_URL}/knowledge/${kbId}/segments/${segmentId}`,
|
|
data,
|
|
);
|
|
}
|
|
|
|
/** 手动添加分段 */
|
|
export async function addKnowledgeSegmentApi(
|
|
kbId: string,
|
|
docId: string,
|
|
data: { content: string; keywords?: string[] },
|
|
) {
|
|
return requestClient.post<KnowledgeSegment>(
|
|
`${BASE_URL}/knowledge/${kbId}/documents/${docId}/segments`,
|
|
data,
|
|
);
|
|
}
|
|
|
|
/** 删除分段 */
|
|
export async function deleteKnowledgeSegmentApi(
|
|
kbId: string,
|
|
segmentId: string,
|
|
) {
|
|
return requestClient.delete(
|
|
`${BASE_URL}/knowledge/${kbId}/segments/${segmentId}`,
|
|
);
|
|
}
|
|
|
|
/** 知识库检索 */
|
|
export async function retrieveKnowledgeApi(data: {
|
|
knowledge_base_ids: string[];
|
|
metadata_filter?: Record<string, any>;
|
|
query: string;
|
|
rerank_enabled?: boolean;
|
|
rerank_model_id?: string;
|
|
retrieval_mode?: string;
|
|
score_threshold?: number;
|
|
top_k?: number;
|
|
}) {
|
|
return requestClient.post<KnowledgeRetrievalResponse>(
|
|
`${BASE_URL}/knowledge/retrieve`,
|
|
data,
|
|
);
|
|
}
|
|
|
|
/** 分块预览 */
|
|
export async function chunkPreviewApi(
|
|
kbId: string,
|
|
data: {
|
|
chunk_overlap?: number;
|
|
chunk_size?: number;
|
|
chunk_strategy?: string;
|
|
file_id: string;
|
|
process_rules?: Record<string, any>;
|
|
separator?: string;
|
|
},
|
|
) {
|
|
return requestClient.post<ChunkPreviewResponse>(
|
|
`${BASE_URL}/knowledge/${kbId}/chunk-preview`,
|
|
data,
|
|
);
|
|
}
|
|
|
|
/** 批量重新索引所有文档 */
|
|
export async function reindexAllDocumentsApi(kbId: string) {
|
|
return requestClient.post(
|
|
`${BASE_URL}/knowledge/${kbId}/documents/reindex-all`,
|
|
);
|
|
}
|
|
|
|
// ============ 标注管理 API ============
|
|
|
|
/** 标注 */
|
|
export interface KnowledgeAnnotation {
|
|
id: string;
|
|
knowledge_base_id: string;
|
|
question: string;
|
|
answer: string;
|
|
embedding_status: string;
|
|
hit_count: number;
|
|
enabled: boolean;
|
|
sys_create_datetime?: string;
|
|
sys_update_datetime?: string;
|
|
}
|
|
|
|
/** 获取标注列表 */
|
|
export async function getAnnotationListApi(
|
|
kbId: string,
|
|
params?: { keyword?: string; page?: number; pageSize?: number },
|
|
) {
|
|
return requestClient.get<PaginatedResponse<KnowledgeAnnotation>>(
|
|
`${BASE_URL}/knowledge/${kbId}/annotations`,
|
|
{ params },
|
|
);
|
|
}
|
|
|
|
/** 创建标注 */
|
|
export async function createAnnotationApi(
|
|
kbId: string,
|
|
data: { answer: string; question: string },
|
|
) {
|
|
return requestClient.post<KnowledgeAnnotation>(
|
|
`${BASE_URL}/knowledge/${kbId}/annotations`,
|
|
data,
|
|
);
|
|
}
|
|
|
|
/** 更新标注 */
|
|
export async function updateAnnotationApi(
|
|
kbId: string,
|
|
annotationId: string,
|
|
data: { answer?: string; enabled?: boolean; question?: string },
|
|
) {
|
|
return requestClient.put<KnowledgeAnnotation>(
|
|
`${BASE_URL}/knowledge/${kbId}/annotations/${annotationId}`,
|
|
data,
|
|
);
|
|
}
|
|
|
|
/** 删除标注 */
|
|
export async function deleteAnnotationApi(kbId: string, annotationId: string) {
|
|
return requestClient.delete(
|
|
`${BASE_URL}/knowledge/${kbId}/annotations/${annotationId}`,
|
|
);
|
|
}
|
|
|
|
/** 重新向量化标注 */
|
|
export async function reindexAnnotationsApi(kbId: string) {
|
|
return requestClient.post(
|
|
`${BASE_URL}/knowledge/${kbId}/annotations/reindex`,
|
|
);
|
|
}
|
|
|
|
// ============ 命中统计 API ============
|
|
|
|
/** 命中统计项 */
|
|
export interface HitStatItem {
|
|
segment_id: string;
|
|
document_id: string;
|
|
document_name: string;
|
|
position: number;
|
|
content_preview: string;
|
|
hit_count: number;
|
|
hit_percentage: number;
|
|
enabled: boolean;
|
|
}
|
|
|
|
/** 命中统计响应 */
|
|
export interface HitStatsResponse {
|
|
items: HitStatItem[];
|
|
total_hits: number;
|
|
total_segments: number;
|
|
zero_hit_count: number;
|
|
}
|
|
|
|
/** 获取命中统计 */
|
|
export async function getHitStatsApi(
|
|
kbId: string,
|
|
params?: { includeZero?: boolean; topN?: number },
|
|
) {
|
|
return requestClient.get<HitStatsResponse>(
|
|
`${BASE_URL}/knowledge/${kbId}/hit-stats`,
|
|
{ params },
|
|
);
|
|
}
|
|
|
|
// ============ 检索日志 API ============
|
|
|
|
/** 检索日志 */
|
|
export interface RetrievalLog {
|
|
id: string;
|
|
query: string;
|
|
knowledge_base_ids: string[];
|
|
retrieval_mode: string;
|
|
top_k: number;
|
|
score_threshold: number;
|
|
result_count: number;
|
|
results?: Array<{ kb_id: string; score: number; segment_id: string }>;
|
|
rerank_applied: string;
|
|
elapsed_time: number;
|
|
source?: string;
|
|
user_id?: string;
|
|
sys_create_datetime?: string;
|
|
}
|
|
|
|
/** 获取检索日志列表 */
|
|
export async function getRetrievalLogsApi(params?: {
|
|
keyword?: string;
|
|
knowledgeBaseId?: string;
|
|
page?: number;
|
|
pageSize?: number;
|
|
}) {
|
|
return requestClient.get<PaginatedResponse<RetrievalLog>>(
|
|
`${BASE_URL}/knowledge/retrieval-logs`,
|
|
{ params },
|
|
);
|
|
}
|