Files
xinmi/frontend/src/api/agent/index.ts
T
yawan f7fc992f57
Anydoc / anydoc parser engine (push) Canceled after 0s
App / Format, vet, test, and build (push) Canceled after 0s
CLI / test (macos-latest / go 1.26) (push) Canceled after 0s
CLI / test (ubuntu-latest / go 1.26) (push) Canceled after 0s
CLI / test (windows-latest / go 1.26) (push) Canceled after 0s
Build and Push Docker Image / build-ui (push) Canceled after 0s
Build and Push Docker Image / build-docreader (push) Canceled after 0s
Build and Push Docker Image / build-sandbox (push) Canceled after 0s
Build and Push Docker Image / build-app (amd64, linux/amd64, ubuntu-latest) (push) Canceled after 0s
Build and Push Docker Image / build-app (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
DocReader / Python tests and Go client tests (push) Canceled after 0s
Build & Publish (dsh-weknora) / Typecheck, test, pack (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (pinned) (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (latest, advisory) (push) Canceled after 0s
Frontend / Test, type-check, and build (push) Canceled after 0s
Go Lint Cache / warm lint cache (.) (push) Canceled after 0s
Go Lint Cache / warm lint cache (cli) (push) Canceled after 0s
Go Lint Cache / warm lint cache (client) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.10) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.11) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.12) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.13) (push) Canceled after 0s
Build and Push Docker Image / merge (push) Canceled after 0s
Build & Publish (dsh-weknora) / Publish to npm (push) Canceled after 0s
Build & Publish (mcp-server) / Build sdist + wheel (push) Canceled after 0s
Build & Publish (mcp-server) / Publish to PyPI (push) Canceled after 0s
WeKnora deployment source with the reviewed wiki identity, summary and recovery fixes
2026-09-22 16:19:06 +08:00

429 lines
16 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { get, post, put, del } from "../../utils/request";
// 智能体配置
// 智能推理下的智能体类型预设 ID
// 'rag-qa' : 经典文档/FAQ 分块 RAG
// 'wiki-qa' : Wiki 图谱导航问答
// 'hybrid-rag-wiki': Wiki + 分块混合检索
// 'custom' : 完全自定义(不应用预设)
export type AgentType = 'rag-qa' | 'wiki-qa' | 'hybrid-rag-wiki' | 'data-analysis' | 'custom';
export interface QuestionSuggestionConfig {
starters: {
enabled: boolean;
mode: 'curated' | 'knowledge' | 'hybrid';
items: string[];
count: number;
};
follow_ups: {
enabled: boolean;
mode: 'generated' | 'knowledge' | 'hybrid';
count: number;
model_id?: string;
additional_instruction?: string;
categories: Array<'clarify' | 'deepen' | 'action'>;
max_context_turns: number;
suppress_on_fallback: boolean;
suppress_when_answer_asks_question: boolean;
knowledge_fallback: boolean;
allow_regenerate: boolean;
};
}
export type AgentRole = '' | 'general' | 'coordinator' | 'production' | 'qc' | 'service' | 'training_map';
export interface CustomAgentConfig {
// ===== 基础设置 =====
role?: AgentRole;
content_tags?: string[];
fusion_agent_ids?: string[];
agent_mode?: 'quick-answer' | 'smart-reasoning'; // 运行模式:quick-answer=RAG模式, smart-reasoning=ReAct Agent模式
// 智能推理模式下的类型预设,用于一键应用"系统提示词 + 工具 + KB 兼容性"组合
// 仅在 agent_mode === 'smart-reasoning' 时生效;quick-answer 模式忽略
agent_type?: AgentType;
system_prompt?: string; // 统一系统提示词(使用 {{web_search_status}} 占位符动态控制行为)
system_prompt_id?: string; // 引用的 prompt template ID(预设会填入此字段)
context_template?: string; // 上下文模板(普通模式)
// ===== 模型设置 =====
model_id?: string;
rerank_model_id?: string; // ReRank 模型 ID
temperature?: number;
max_completion_tokens?: number; // 0 = 跟随系统默认(快速问答 2048;智能推理 4096,绑沙箱可写文件时 24576)。大于 0 为自定义上限
thinking?: boolean; // 是否启用思考模式(支持扩展思考的模型)
citation_enabled?: boolean; // 是否在最终回答中输出知识库/网页来源引用(默认开启)
// ===== Agent模式设置 =====
max_iterations?: number; // 最大迭代次数;-1 表示不限制
llm_call_timeout?: number; // LLM调用超时时间(秒)
allowed_tools?: string[]; // 允许的工具
reflection_enabled?: boolean; // 是否启用反思
// MCP服务选择模式:all=全部启用的MCP服务, selected=指定服务, none=不使用MCP
mcp_selection_mode?: 'all' | 'selected' | 'none';
mcp_services?: string[]; // 选择的MCP服务ID列表
// 对话中触发 OAuth 授权时的等待超时(秒):到点后自动跳过授权提示。
// <=0 时使用服务端默认超时。仅对使用 OAuth 的 MCP 服务生效。
mcp_auth_wait_timeout?: number;
// ===== Skills设置(仅Agent模式)=====
// Skills选择模式:all=全部预装, selected=指定, none=不使用
skills_selection_mode?: 'all' | 'selected' | 'none';
selected_skills?: string[]; // 选择的Skill名称列表
instruction_skill_ids?: string[]; // Markdown 指令技能,无需沙箱
// ===== 沙箱设置 =====
// 该智能体的技能脚本运行在哪个沙箱配置上;为空表示不启用沙箱执行。
// 指向逻辑配置而非某个具体版本,凭据轮换时无需重新指派每个智能体。
sandbox_config_id?: string;
// ===== 知识库设置 =====
// 知识库选择模式:all=全部知识库, selected=指定知识库, none=不使用知识库
kb_selection_mode?: 'all' | 'selected' | 'none';
knowledge_bases?: string[];
// 是否仅在显式 @ 提及时检索知识库(默认: false)
// true: 只有用户通过 @ 明确提及知识库/文档时才检索
// false: 根据 kb_selection_mode 自动检索知识库
retrieve_kb_only_when_mentioned?: boolean;
// ===== 图片上传/多模态设置 =====
image_upload_enabled?: boolean; // 是否启用图片上传(默认: false)
vlm_model_id?: string; // VLM模型ID(图片分析用)
image_storage_provider?: string; // 图片存储提供商
audio_upload_enabled?: boolean; // 是否启用音频上传/ASR转录(默认: false)
asr_model_id?: string; // ASR模型ID(音频转录用)
// 附件图片理解 / 扫描件 OCR 开关(默认: false,开启会增加解析耗时)
attachment_image_understanding?: boolean;
// 扫描件 OCR 最大页数(0 = 使用全局默认 WEKNORA_CHAT_ATTACHMENT_OCR_MAX_PAGES)
attachment_ocr_max_pages?: number;
// 单轮问答等待附件解析完成的最长时间(秒,0 = 使用全局默认 WEKNORA_CHAT_ATTACHMENT_WAIT_TIMEOUT_SEC)
attachment_parse_wait_timeout_sec?: number;
// ===== 聊天附件解析引擎策略 =====
// 按文件类型选择解析引擎;优先级:请求 parser_engine > 智能体规则 > 租户规则 > auto
chat_parser_engine_rules?: { file_types: string[]; engine: string }[];
// ===== 文件类型限制 =====
// 支持的文件类型(如 ["csv", "xlsx", "xls"])
// 为空表示支持所有文件类型
supported_file_types?: string[];
// ===== 网络搜索设置 =====
web_search_enabled?: boolean;
web_search_provider_id?: string;
web_search_max_results?: number;
// ===== 多轮对话设置 =====
multi_turn_enabled?: boolean; // 是否启用多轮对话
history_turns?: number; // 保留历史轮数
// ===== 长期记忆 =====
// 该智能体是否可以读取用户的长期记忆。
// 缺省(旧数据)等同于 true:这是一个只能"关"的开关,空间设置关闭时
// 这里打开也不会生效。
memory_enabled?: boolean;
// ===== 检索策略设置 =====
embedding_top_k?: number; // 向量召回TopK
keyword_threshold?: number; // 关键词召回阈值
vector_threshold?: number; // 向量召回阈值
rerank_top_k?: number; // 重排TopK
rerank_threshold?: number; // 重排阈值
// ===== 高级设置(主要用于普通模式)=====
enable_query_expansion?: boolean; // 是否启用查询扩展
enable_rewrite?: boolean; // 是否启用问题改写
rewrite_prompt_system?: string; // 改写系统提示词
rewrite_prompt_user?: string; // 改写用户提示词模板
fallback_strategy?: 'fixed' | 'model'; // 兜底策略
fallback_response?: string; // 固定兜底回复
fallback_prompt?: string; // 兜底提示词(模型生成时)
// 意图提示词:非检索意图(问候、闲聊等)时覆盖主系统提示词
intent_prompts?: Record<string, string>;
// ===== 已废弃字段(保留兼容)=====
welcome_message?: string;
question_suggestions?: QuestionSuggestionConfig;
}
// 智能体
export interface CustomAgent {
digital_human?: { id: string; name: string; applied_version: number; active_version: number };
enabled?: boolean;
visibility?: 'private' | 'global';
id: string;
name: string;
description?: string;
avatar?: string;
is_builtin: boolean;
tenant_id?: number;
created_by?: string;
// creator_name 由后端 list 接口批量回填,仅用于列表卡片来源徽章。
creator_name?: string;
config: CustomAgentConfig;
created_at?: string;
updated_at?: string;
}
// 创建智能体请求
export interface CreateAgentRequest {
name: string;
description?: string;
avatar?: string;
config?: CustomAgentConfig;
}
// 更新智能体请求
export interface UpdateAgentRequest {
name: string;
description?: string;
avatar?: string;
config?: CustomAgentConfig;
}
// 内置智能体 ID(常用的保留常量,便于代码引用)
export const BUILTIN_QUICK_ANSWER_ID = 'builtin-quick-answer';
export const BUILTIN_SMART_REASONING_ID = 'builtin-smart-reasoning';
// AgentMode 常量
export const AGENT_MODE_QUICK_ANSWER = 'quick-answer';
export const AGENT_MODE_SMART_REASONING = 'smart-reasoning';
// Deprecated: Use BUILTIN_QUICK_ANSWER_ID instead
export const BUILTIN_AGENT_NORMAL_ID = BUILTIN_QUICK_ANSWER_ID;
// Deprecated: Use BUILTIN_SMART_REASONING_ID instead
export const BUILTIN_AGENT_AGENT_ID = BUILTIN_SMART_REASONING_ID;
// 获取智能体列表(包括内置智能体)
// disabled_own_agent_ids: 当前空间在对话下拉中停用的「我的」智能体 ID,仅影响本空间
export function listAgents(params?: {
/**
* Optional creator filter; mirrors listKnowledgeBases. Built-in agents
* (is_builtin=true) are always returned regardless of this filter so
* the conversation dropdown never silently loses quick-answer /
* smart-reasoning when a user picks "Created by me".
*/
creator?: 'all' | 'mine' | 'others';
}) {
const qs = params?.creator && params.creator !== 'all' ? `?creator=${params.creator}` : '';
return get<{ data: CustomAgent[]; disabled_own_agent_ids?: string[] }>(`/api/v1/agents${qs}`);
}
// 获取智能体详情
export function getAgentById(id: string) {
return get<{ data: CustomAgent }>(`/api/v1/agents/${id}`);
}
// 创建智能体
export function createAgent(data: CreateAgentRequest) {
return post<{ data: CustomAgent }>('/api/v1/agents', data);
}
export function draftAgent(data: { model_id: string; requirement: string }) {
return post<{ data: CreateAgentRequest }>('/api/v1/agents/draft', data, { timeout: 120000 });
}
// 更新智能体
export function updateAgent(id: string, data: UpdateAgentRequest) {
return put<{ data: CustomAgent }>(`/api/v1/agents/${id}`, data);
}
// 删除智能体
export function deleteAgent(id: string) {
return del<{ success: boolean }>(`/api/v1/agents/${id}`);
}
// 复制智能体
export function copyAgent(id: string) {
return post<{ data: CustomAgent }>(`/api/v1/agents/${id}/copy`);
}
// 判断是否为内置智能体(通过 agent.is_builtin 字段或 ID 前缀判断)
export function isBuiltinAgent(agentId: string): boolean {
return agentId.startsWith('builtin-');
}
// 占位符定义
export interface PlaceholderDefinition {
name: string;
label: string;
description: string;
}
// 占位符响应
export interface PlaceholdersResponse {
all: PlaceholderDefinition[];
system_prompt: PlaceholderDefinition[];
agent_system_prompt: PlaceholderDefinition[];
context_template: PlaceholderDefinition[];
rewrite_system_prompt: PlaceholderDefinition[];
rewrite_prompt: PlaceholderDefinition[];
fallback_prompt: PlaceholderDefinition[];
}
// 获取占位符定义
export function getPlaceholders() {
return get<{ data: PlaceholdersResponse }>('/api/v1/agents/placeholders');
}
// ===== 智能体类型预设 =====
// 后端 kb_filter 结构(见 internal/types/agent_type_preset.go)
export interface AgentTypeKBFilter {
any_of?: string[]; // KB 至少拥有其一
all_of?: string[]; // KB 必须全部拥有
none_of?: string[]; // KB 必须全部不拥有
}
// KB 能力标签(后端 types.KBCapabilities 的 JSON)
export interface KBCapabilities {
vector: boolean;
keyword: boolean;
wiki: boolean;
graph: boolean;
faq: boolean;
}
// 预设的"自动填充"配置载荷:仅包含被预设覆盖的字段;其他字段不动
export interface AgentTypePresetConfig {
system_prompt_id?: string;
temperature?: number;
max_iterations?: number;
allowed_tools?: string[];
retain_retrieval_history?: boolean;
faq_priority_enabled?: boolean;
web_search_enabled?: boolean;
supported_file_types?: string[];
kb_selection_mode?: 'all' | 'selected' | 'none';
}
export interface AgentTypePresetI18n {
label: string;
description: string;
}
export interface AgentTypePreset {
id: AgentType;
i18n: Record<string, AgentTypePresetI18n>;
config?: AgentTypePresetConfig; // 为空表示"自定义"类型(无预设)
kb_filter?: AgentTypeKBFilter; // 为空表示所有 KB 可选
}
// 拉取类型预设列表(编辑器用)
export function getAgentTypePresets() {
return get<{ data: AgentTypePreset[] }>('/api/v1/agents/type-presets');
}
// ===== IM渠道 =====
export interface IMChannel {
id: string;
tenant_id?: number;
agent_id: string;
// 'lark' is Feishu's international edition; it shares Feishu's credentials and modes.
platform: 'wecom' | 'feishu' | 'lark' | 'slack' | 'telegram' | 'dingtalk' | 'mattermost' | 'wechat' | 'qqbot' | 'yunzhijia';
name: string;
enabled: boolean;
mode: 'webhook' | 'websocket' | 'longpoll';
output_mode: 'stream' | 'full';
session_mode?: 'user' | 'thread';
knowledge_base_id?: string;
credentials: Record<string, any>;
created_at?: string;
updated_at?: string;
}
export function listIMChannels(agentId: string) {
return get<{ data: IMChannel[] }>(`/api/v1/agents/${agentId}/im-channels`);
}
// Tenant-wide overview row. Credentials are intentionally omitted — use
// listIMChannels(agentId) when you need to edit a specific channel.
export interface IMChannelOverview {
id: string;
tenant_id: number;
agent_id: string;
agent_name: string; // localized built-in name when the agent is built-in
platform: IMChannel['platform'];
name: string;
enabled: boolean;
mode: IMChannel['mode'];
output_mode: IMChannel['output_mode'];
session_mode?: IMChannel['session_mode'];
bot_identity: string;
created_at: string;
updated_at: string;
}
export function listAllIMChannels() {
return get<{ data: IMChannelOverview[] }>('/api/v1/im-channels');
}
export function createIMChannel(agentId: string, data: Partial<IMChannel>) {
return post<{ data: IMChannel }>(`/api/v1/agents/${agentId}/im-channels`, data);
}
export function updateIMChannel(id: string, data: Partial<IMChannel>) {
return put<{ data: IMChannel }>(`/api/v1/im-channels/${id}`, data);
}
export function deleteIMChannel(id: string) {
return del<{ success: boolean }>(`/api/v1/im-channels/${id}`);
}
export function toggleIMChannel(id: string) {
return post<{ data: IMChannel }>(`/api/v1/im-channels/${id}/toggle`);
}
// ===== 推荐问题 =====
// 推荐问题
export interface SuggestedQuestion {
question: string;
source: 'faq' | 'document' | 'agent_config' | 'wiki';
knowledge_base_id?: string;
}
// 获取智能体推荐问题
// 根据智能体关联的知识库范围返回推荐问题,用于前端对话面板快捷提问
export function getSuggestedQuestions(
agentId: string,
params?: {
knowledge_base_ids?: string[];
knowledge_ids?: string[];
tag_scopes?: Array<{ knowledge_base_id: string; tag_ids: string[] }>;
limit?: number;
}
) {
const query = new URLSearchParams();
if (params?.knowledge_base_ids?.length) query.set('knowledge_base_ids', params.knowledge_base_ids.join(','));
if (params?.knowledge_ids?.length) query.set('knowledge_ids', params.knowledge_ids.join(','));
if (params?.tag_scopes?.length) query.set('tag_scopes', JSON.stringify(params.tag_scopes));
if (params?.limit) query.set('limit', String(params.limit));
const qs = query.toString();
return get<{ data: { questions: SuggestedQuestion[] } }>(`/api/v1/agents/${agentId}/suggested-questions${qs ? '?' + qs : ''}`);
}
// ===== WeChat QR Code Login =====
export interface WeChatQRCodeResult {
qrcode_url: string;
qrcode: string;
}
export interface WeChatQRCodeStatus {
status: 'wait' | 'scaned' | 'confirmed' | 'expired';
credentials?: {
bot_token: string;
ilink_bot_id: string;
ilink_user_id: string;
};
baseurl?: string;
}
export function getWeChatQRCode() {
return post<{ data: WeChatQRCodeResult }>('/api/v1/wechat/qrcode');
}
export function pollWeChatQRCodeStatus(qrcode: string) {
return post<{ data: WeChatQRCodeStatus }>('/api/v1/wechat/qrcode/status', { qrcode });
}