Files
aiagent/frontend/src/utils/agentSkills.ts

77 lines
2.8 KiB
TypeScript
Raw Normal View History

/**
* Agent / LLM skills
*/
import type { WorkflowNode } from '@/types'
/** 与后端 tools_bootstrap 内置工具一致,用于列表展示与配置勾选 */
export const BUILTIN_SKILL_OPTIONS: { name: string; label: string }[] = [
{ name: 'http_request', label: 'HTTP 请求' },
{ name: 'file_read', label: '读文件' },
{ name: 'file_write', label: '写文件' },
{ name: 'text_analyze', label: '文本分析' },
{ name: 'datetime', label: '日期时间' },
{ name: 'math_calculate', label: '数学计算' },
{ name: 'system_info', label: '系统信息' },
{ name: 'json_process', label: 'JSON 处理' },
{ name: 'database_query', label: '数据库查询' },
{ name: 'adb_log', label: 'ADB 日志' }
]
export const BUILTIN_SKILL_LABELS: Record<string, string> = Object.fromEntries(
BUILTIN_SKILL_OPTIONS.map((o) => [o.name, o.label])
)
function isLlmNode(n: WorkflowNode): boolean {
const t = (n.type || '').toLowerCase()
const dt = (n.data?.type || '').toLowerCase()
return t === 'llm' || t === 'template' || dt === 'llm'
}
/** 工作流中所有 LLM 节点上已选工具的并集(去重排序) */
export function extractSkillToolNames(workflow_config: { nodes?: WorkflowNode[] } | null | undefined): string[] {
const set = new Set<string>()
for (const n of workflow_config?.nodes || []) {
if (!isLlmNode(n)) continue
const raw = n.data?.tools ?? n.data?.selected_tools
if (Array.isArray(raw)) {
raw.forEach((x) => set.add(String(x)))
}
}
return Array.from(set).sort()
}
/**
* llm-unified LLM LLM
*/
export function findPrimaryLlmNodeForTools(nodes: WorkflowNode[] | undefined): WorkflowNode | null {
if (!nodes?.length) return null
const byId = nodes.find((n) => n.id === 'llm-unified' && isLlmNode(n))
if (byId) return byId
const withTools = nodes.find(
(n) =>
isLlmNode(n) &&
(n.data?.enable_tools === true ||
(Array.isArray(n.data?.tools) && n.data.tools.length > 0) ||
(Array.isArray(n.data?.selected_tools) && n.data.selected_tools.length > 0))
)
if (withTools) return withTools
return nodes.find((n) => isLlmNode(n)) || null
}
export function patchWorkflowSkillTools(
workflow_config: { nodes: WorkflowNode[]; edges: unknown[] },
toolNames: string[]
): { nodes: WorkflowNode[]; edges: unknown[] } {
const wf = JSON.parse(JSON.stringify(workflow_config)) as { nodes: WorkflowNode[]; edges: unknown[] }
const target = findPrimaryLlmNodeForTools(wf.nodes)
if (!target) return wf
const names = [...new Set(toolNames)].filter(Boolean).sort()
if (!target.data) target.data = {}
target.data.enable_tools = names.length > 0
target.data.tools = names
target.data.selected_tools = names
return wf
}