WeKnora deployment source with the reviewed wiki identity, summary and recovery fixes
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

This commit is contained in:
yawan
2026-09-22 16:19:06 +08:00
commit f7fc992f57
3929 changed files with 1006607 additions and 0 deletions
+428
View File
@@ -0,0 +1,428 @@
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 });
}