perf: 优化智能体与工作流幕布渲染性能
- 分阶段加载智能体配置并按需缓存 MCP 工具 - 合并画布状态更新与节点尺寸监听,启用大图可视区域渲染和静态连线 - 隔离 Tinyflow Store 实例并补充数据同步与回归测试
This commit is contained in:
@@ -31,13 +31,36 @@ function firstText(...values: unknown[]) {
|
||||
return matched ? String(matched).trim() : '';
|
||||
}
|
||||
|
||||
function createKnowledgeOptionLookup(options: AgentOption[]) {
|
||||
const lookup = new Map<string, AgentOption>();
|
||||
options.forEach((option) => {
|
||||
const key = String(option.value);
|
||||
if (!lookup.has(key)) {
|
||||
lookup.set(key, option);
|
||||
}
|
||||
});
|
||||
return lookup;
|
||||
}
|
||||
|
||||
function createToolOptionLookup(options: AgentOption[]) {
|
||||
const lookup = new Map<string, AgentOption>();
|
||||
options.forEach((option) => {
|
||||
const raw = option.raw || {};
|
||||
[option.value, raw.id, raw.mcpId].forEach((value) => {
|
||||
const key = String(value || '');
|
||||
if (key && !lookup.has(key)) {
|
||||
lookup.set(key, option);
|
||||
}
|
||||
});
|
||||
});
|
||||
return lookup;
|
||||
}
|
||||
|
||||
function buildKnowledgeTitle(
|
||||
binding: AgentKnowledgeBinding,
|
||||
options: AgentOption[],
|
||||
optionLookup: Map<string, AgentOption>,
|
||||
) {
|
||||
const matchedOption = options.find(
|
||||
(item) => String(item.value) === String(binding.knowledgeId),
|
||||
);
|
||||
const matchedOption = optionLookup.get(String(binding.knowledgeId));
|
||||
return firstText(
|
||||
binding.resourceSummary?.title,
|
||||
binding.resourceSummary?.name,
|
||||
@@ -59,22 +82,18 @@ function buildKnowledgeTitle(
|
||||
|
||||
function findMatchedToolOption(
|
||||
binding: AgentToolBinding,
|
||||
options: AgentOption[],
|
||||
optionLookup: Map<string, AgentOption>,
|
||||
) {
|
||||
const targetId = String(binding.targetId || '');
|
||||
if (!targetId) return undefined;
|
||||
return options.find((item) => {
|
||||
const raw = item.raw || {};
|
||||
return (
|
||||
String(item.value) === targetId ||
|
||||
String(raw.id || '') === targetId ||
|
||||
String(raw.mcpId || '') === targetId
|
||||
);
|
||||
});
|
||||
return optionLookup.get(targetId);
|
||||
}
|
||||
|
||||
function buildToolTitle(binding: AgentToolBinding, options: AgentOption[] = []) {
|
||||
const matchedOption = findMatchedToolOption(binding, options);
|
||||
function buildToolTitle(
|
||||
binding: AgentToolBinding,
|
||||
optionLookup: Map<string, AgentOption>,
|
||||
matchedOption = findMatchedToolOption(binding, optionLookup),
|
||||
) {
|
||||
return firstText(
|
||||
binding.resourceSummary?.title,
|
||||
binding.resourceSummary?.name,
|
||||
@@ -99,11 +118,11 @@ function buildToolTitle(binding: AgentToolBinding, options: AgentOption[] = [])
|
||||
function buildToolDetail(
|
||||
binding: AgentToolBinding,
|
||||
fallback: string,
|
||||
options: AgentOption[] = [],
|
||||
optionLookup: Map<string, AgentOption>,
|
||||
) {
|
||||
if (String(binding.toolType || '').toUpperCase() === 'MCP') {
|
||||
const matchedOption = findMatchedToolOption(binding, options);
|
||||
const resourceName = buildToolTitle(binding, options);
|
||||
const matchedOption = findMatchedToolOption(binding, optionLookup);
|
||||
const resourceName = buildToolTitle(binding, optionLookup, matchedOption);
|
||||
const tools =
|
||||
binding.resourceSummary?.tools ||
|
||||
binding.resourceSnapshot?.tools ||
|
||||
@@ -116,7 +135,7 @@ function buildToolDetail(
|
||||
return resourceName || fallback;
|
||||
}
|
||||
const toolName = firstText(binding.toolName);
|
||||
const resourceName = buildToolTitle(binding, options);
|
||||
const resourceName = buildToolTitle(binding, optionLookup);
|
||||
if (toolName && resourceName && toolName !== resourceName) {
|
||||
return `${resourceName} / ${toolName}`;
|
||||
}
|
||||
@@ -214,6 +233,16 @@ export function useAgentStudioModel(
|
||||
const positionOf = (nodeId: string, fallback: { x: number; y: number }) =>
|
||||
layout?.nodePositions?.[nodeId] || fallback;
|
||||
const size = canvasSize?.();
|
||||
const resolvedKnowledgeOptions = knowledgeOptions?.() || [];
|
||||
const resolvedToolOptions = toolOptions?.() || {};
|
||||
const knowledgeOptionLookup = createKnowledgeOptionLookup(
|
||||
resolvedKnowledgeOptions,
|
||||
);
|
||||
const toolOptionLookups = {
|
||||
mcp: createToolOptionLookup(resolvedToolOptions.mcp || []),
|
||||
plugin: createToolOptionLookup(resolvedToolOptions.plugin || []),
|
||||
workflow: createToolOptionLookup(resolvedToolOptions.workflow || []),
|
||||
};
|
||||
const occupiedPositions: Array<{ x: number; y: number }> = Object.values(
|
||||
layout?.nodePositions || {},
|
||||
);
|
||||
@@ -238,7 +267,7 @@ export function useAgentStudioModel(
|
||||
|
||||
const knowledgeNodes = state.knowledgeBindings.map((binding, index) => {
|
||||
const nodeId = `knowledge:${binding.localId}`;
|
||||
const title = buildKnowledgeTitle(binding, knowledgeOptions?.() || []);
|
||||
const title = buildKnowledgeTitle(binding, knowledgeOptionLookup);
|
||||
const position = resolveCapabilityNodePosition({
|
||||
canvasSize: size,
|
||||
fallbackIndex: index,
|
||||
@@ -270,10 +299,10 @@ export function useAgentStudioModel(
|
||||
const isWorkflow = toolType === 'WORKFLOW';
|
||||
const isMcp = toolType === 'MCP';
|
||||
const matchedOptions = isWorkflow
|
||||
? toolOptions?.().workflow || []
|
||||
? toolOptionLookups.workflow
|
||||
: isMcp
|
||||
? toolOptions?.().mcp || []
|
||||
: toolOptions?.().plugin || [];
|
||||
? toolOptionLookups.mcp
|
||||
: toolOptionLookups.plugin;
|
||||
const fallback = isWorkflow
|
||||
? '待选择工作流'
|
||||
: isMcp
|
||||
|
||||
Reference in New Issue
Block a user