Commit abf55760 authored by AI-甘富林's avatar AI-甘富林

ai对话记忆修复,表格展示

parent f5554d02
...@@ -363,6 +363,7 @@ interface GenUIResponse { ...@@ -363,6 +363,7 @@ interface GenUIResponse {
gap?: string; gap?: string;
components: any[]; components: any[];
}; };
ui_schema_text?: string;
suggested_actions?: string[]; suggested_actions?: string[];
} }
...@@ -370,8 +371,97 @@ interface GenUIResponse { ...@@ -370,8 +371,97 @@ interface GenUIResponse {
// 统一 AI 大模型调用(通过 _shared/aiProvider) // 统一 AI 大模型调用(通过 _shared/aiProvider)
// ======================== // ========================
/** 将 ui_schema 组件转为可存储、可展示的 Markdown 文本 */
function uiSchemaToMarkdown(uiSchema: any): string {
if (!uiSchema?.components || !Array.isArray(uiSchema.components)) return "";
const parts: string[] = [];
for (const comp of uiSchema.components) {
const props = comp.props || {};
switch (comp.type) {
case 'data_table': {
const { title, columns, rows } = props;
if (!columns || !rows) break;
let table = '';
if (title) table += `**${title}**\n\n`;
// 表头
table += '| ' + columns.map((c: any) => c.label || c.key).join(' | ') + ' |\n';
table += '| ' + columns.map(() => '---').join(' | ') + ' |\n';
// 数据行
for (const row of rows) {
table += '| ' + columns.map((c: any) => row[c.key] != null ? String(row[c.key]) : '').join(' | ') + ' |\n';
}
parts.push(table);
break;
}
case 'stats_row': {
const { items } = props;
if (!items || !Array.isArray(items)) break;
const statsText = items.map((item: any) =>
`- **${item.label}**: ${item.value}`
).join('\n');
parts.push(statsText);
break;
}
case 'insight_feed': {
const { title, insights } = props;
if (title) parts.push(`**${title}**`);
if (insights && Array.isArray(insights)) {
for (const ins of insights) {
const emoji = ins.type === 'warning' ? '⚠️' : ins.type === 'success' ? '✅' : ins.type === 'error' ? '❌' : 'ℹ️';
parts.push(`- ${emoji} **${ins.title}**: ${ins.description || ''}`);
}
}
break;
}
case 'alert': {
const alertEmoji = props.type === 'error' ? '❌' : props.type === 'warning' ? '⚠️' : props.type === 'success' ? '✅' : 'ℹ️';
parts.push(`> ${alertEmoji} **${props.title || ''}**\n> ${props.description || ''}`);
break;
}
case 'chart': {
const { title, data } = props;
if (title) parts.push(`**${title}**`);
if (data && Array.isArray(data)) {
for (const d of data) {
parts.push(`- ${d.label}: ${d.value}`);
}
}
break;
}
case 'text': {
parts.push(props.content || '');
break;
}
case 'progress_bar': {
const pct = props.target ? Math.round((props.current / props.target) * 100) : 0;
parts.push(`- **${props.label}**: ${props.current}/${props.target} (${pct}%)`);
break;
}
case 'approval_list': {
const { title, approvals } = props;
if (title) parts.push(`**${title}**`);
if (approvals && Array.isArray(approvals)) {
for (const a of approvals) {
const prio = a.priority === 'high' ? '🔴' : a.priority === 'medium' ? '🟡' : '🟢';
parts.push(`- ${prio} **${a.title}** — ${a.description || ''} (发起人: ${a.agent || '-'})`);
}
}
break;
}
}
}
return parts.join('\n\n');
}
/** /**
* 将 AI 返回的原始文本解析为 GenUIResponse * 将 AI 返回的原始文本解析为 GenUIResponse
* - 提取 ```json 前的纯文本作为 textAnswer
* - 解析 JSON 中的 ui_schema
* - 将 ui_schema 组件转为 Markdown 追加到 answer,确保存储和展示都有完整数据
*/ */
function parseAIResponse(raw: string): GenUIResponse { function parseAIResponse(raw: string): GenUIResponse {
let jsonContent = raw.trim(); let jsonContent = raw.trim();
...@@ -417,12 +507,16 @@ function parseAIResponse(raw: string): GenUIResponse { ...@@ -417,12 +507,16 @@ function parseAIResponse(raw: string): GenUIResponse {
}); });
} }
console.log(`[CozeLangchain] AI JSON parsed, has ui_schema: ${!!uiSchema}`); // 将 ui_schema 组件转为 Markdown 文本,供前端存库用(历史消息可读)
const uiSchemaText = uiSchemaToMarkdown(uiSchema);
console.log(`[CozeLangchain] AI JSON parsed, has ui_schema: ${!!uiSchema}, uiSchemaText length: ${uiSchemaText.length}`);
return { return {
// 优先用新格式的纯文本回答,其次用 JSON 内的 answer 字段 // answer 保持干净:纯文本回答,不混入组件数据
answer: textAnswer || parsed.answer || "已为您生成界面", answer: textAnswer || parsed.answer || "已为您生成界面",
ui_schema: uiSchema, ui_schema: uiSchema,
ui_schema_text: uiSchemaText || undefined, // 单独字段,前端拼接存库
suggested_actions: parsed.suggested_actions, suggested_actions: parsed.suggested_actions,
}; };
} catch { } catch {
...@@ -714,6 +808,7 @@ ${dataContext} ...@@ -714,6 +808,7 @@ ${dataContext}
type: "done", type: "done",
answer: genUIResult.answer, answer: genUIResult.answer,
ui_schema: genUIResult.ui_schema, ui_schema: genUIResult.ui_schema,
ui_schema_text: genUIResult.ui_schema_text,
suggested_actions: genUIResult.suggested_actions, suggested_actions: genUIResult.suggested_actions,
agent_type: agentType, agent_type: agentType,
session_id: sessionId, session_id: sessionId,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment