ai-query对接新版freesun-agent接口的分支
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

136 lines
4.4 KiB

'use strict';
const { ensureObjectPayload, toInt } = require('./helpers');
const {
sanitizeQueryBlockConfig,
buildChartSnapshotPayload,
buildTableSnapshotPayload,
buildKpiSnapshotPayload,
} = require('./chartSnapshot');
const { analyzeBlockSnapshotWithPrompt } = require('./ai');
const normalizeOptionalString = value => {
const normalized = String(value || '').trim();
return normalized || null;
};
const deepCloneJson = value => {
if (value === null || value === undefined) return value;
return JSON.parse(JSON.stringify(value));
};
const rewriteAiAnalysisConfig = (config = {}, blockIdMap = null) => {
const nextConfig = deepCloneJson(config) || {};
if (!(blockIdMap instanceof Map) || !blockIdMap.size) {
return sanitizeQueryBlockConfig(nextConfig);
}
const sourceTemplateBlockId = toInt(
nextConfig.sourceTemplateBlockId || nextConfig.sourceBlockId || nextConfig.linkedBlockId
);
if (!sourceTemplateBlockId) return sanitizeQueryBlockConfig(nextConfig);
const resolvedBlockId = blockIdMap.get(String(sourceTemplateBlockId));
if (resolvedBlockId) {
nextConfig.sourceBlockId = resolvedBlockId;
nextConfig.linkedBlockId = resolvedBlockId;
}
delete nextConfig.sourceTemplateBlockId;
return sanitizeQueryBlockConfig(nextConfig);
};
const resolveBlockPayload = async (ctx, options = {}) => {
const normalizedBlockType = String(options?.blockType || 'text').trim().toLowerCase();
const safeConfig = ensureObjectPayload(options?.config || {}, 'config');
const safeSnapshot = deepCloneJson(options?.contentSnapshot) || null;
const dataSourceId = toInt(options?.dataSourceId);
const transaction = options?.transaction || null;
if (normalizedBlockType === 'chart') {
if (!dataSourceId) throw '缺少参数: dataSourceId';
return buildChartSnapshotPayload(
ctx,
dataSourceId,
safeConfig,
transaction,
safeSnapshot
);
}
if (normalizedBlockType === 'table') {
if (!dataSourceId) throw '缺少参数: dataSourceId';
return buildTableSnapshotPayload(ctx, dataSourceId, safeConfig, transaction);
}
if (normalizedBlockType === 'kpi') {
if (!dataSourceId) throw '缺少参数: dataSourceId';
return buildKpiSnapshotPayload(ctx, dataSourceId, safeConfig, transaction);
}
return {
config: sanitizeQueryBlockConfig(safeConfig),
contentSnapshot: safeSnapshot,
};
};
const finalizeResolvedBlockPayload = async (ctx, options = {}) => {
const normalizedBlockType = String(options?.blockType || 'text').trim().toLowerCase();
const baseConfig = ensureObjectPayload(options?.config || {}, 'config');
const safeSnapshot = deepCloneJson(options?.contentSnapshot) || null;
if (normalizedBlockType !== 'ai_analysis') {
return {
config: sanitizeQueryBlockConfig(baseConfig),
contentSnapshot: safeSnapshot,
};
}
const rewrittenConfig = rewriteAiAnalysisConfig(baseConfig, options?.blockIdMap || null);
const sourceBlockId = toInt(rewrittenConfig.sourceBlockId || rewrittenConfig.linkedBlockId);
const prompt = normalizeOptionalString(rewrittenConfig.prompt);
if (!sourceBlockId || !prompt || typeof options?.getCreatedBlockStateByInstanceId !== 'function') {
return {
config: rewrittenConfig,
contentSnapshot: safeSnapshot,
};
}
const sourceBlockState = options.getCreatedBlockStateByInstanceId(sourceBlockId);
if (!sourceBlockState) {
return {
config: rewrittenConfig,
contentSnapshot: safeSnapshot,
};
}
let content = '';
try {
content = await analyzeBlockSnapshotWithPrompt(ctx, {
actionId: `report-block:${sourceBlockState.createdId || sourceBlockId}`,
prompt,
sourceBlock: {
id: sourceBlockState.createdId || sourceBlockId,
blockType: sourceBlockState.blockType,
config: sourceBlockState.config || {},
contentSnapshot: sourceBlockState.contentSnapshot || null,
},
});
} catch (error) {
content = normalizeOptionalString(safeSnapshot?.content)
|| `AI 分析生成失败: ${error?.message || error || '未知错误'}`;
}
return {
config: rewrittenConfig,
contentSnapshot: {
kind: 'ai_analysis',
content,
},
};
};
module.exports = {
resolveBlockPayload,
finalizeResolvedBlockPayload,
rewriteAiAnalysisConfig,
};