fix: 匹配markdown
This commit is contained in:
@@ -60,6 +60,10 @@ export const EnhancedMarkdownRenderer: React.FC<EnhancedMarkdownRendererProps> =
|
||||
try {
|
||||
// 解析Markdown
|
||||
const result = await markdownService.parseMarkdown(content);
|
||||
console.log({
|
||||
content: content.length,
|
||||
result: result.source_text.length
|
||||
})
|
||||
setParseResult(result);
|
||||
|
||||
// 验证文档结构
|
||||
@@ -89,16 +93,90 @@ export const EnhancedMarkdownRenderer: React.FC<EnhancedMarkdownRendererProps> =
|
||||
}
|
||||
}, [parseContent, enableRealTimeParsing]);
|
||||
|
||||
// 渲染单个Markdown节点
|
||||
const renderNode = useCallback((node: MarkdownNode, depth: number = 0): React.ReactNode => {
|
||||
const key = `${node.range?.start?.line || 0}-${node.range?.start?.column || 0}-${depth}`;
|
||||
// 分析节点与引用资源的关联
|
||||
const analyzeNodeGrounding = useCallback((node: MarkdownNode) => {
|
||||
if (!groundingMetadata?.grounding_supports || !parseResult) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 计算节点在原始文本中的字符偏移位置
|
||||
const nodeStartOffset = node.range?.start?.offset || 0;
|
||||
const nodeEndOffset = node.range?.end?.offset || 0;
|
||||
// 查找与当前节点位置重叠的grounding支持信息
|
||||
|
||||
const relatedSupports = groundingMetadata.grounding_supports.filter(support => {
|
||||
// 这里是字符串二进制的offset
|
||||
const segmentStart = support.segment.startIndex;
|
||||
const segmentEnd = support.segment.endIndex;
|
||||
|
||||
const hasOverlap = (nodeEndOffset <= segmentEnd && nodeStartOffset >= segmentStart);
|
||||
// 检查节点范围与grounding片段是否有重叠
|
||||
return hasOverlap;
|
||||
});
|
||||
|
||||
if (relatedSupports.length > 0) {
|
||||
// 获取相关的来源信息
|
||||
const relatedSources = relatedSupports.flatMap(support =>
|
||||
support.groundingChunkIndices.map(index => groundingMetadata.sources[index])
|
||||
).filter(Boolean);
|
||||
|
||||
const analysisResult = {
|
||||
node: {
|
||||
type: node.node_type,
|
||||
content: node.content.substring(0, 100) + (node.content.length > 100 ? '...' : ''),
|
||||
position: {
|
||||
start: nodeStartOffset,
|
||||
end: nodeEndOffset,
|
||||
line: node.range?.start?.line,
|
||||
column: node.range?.start?.column
|
||||
}
|
||||
},
|
||||
groundingInfo: {
|
||||
supportCount: relatedSupports.length,
|
||||
sourceCount: relatedSources.length,
|
||||
sources: relatedSources.map(source => ({
|
||||
title: source.title,
|
||||
uri: source.uri,
|
||||
snippet: source.content?.snippet || 'No snippet available'
|
||||
})),
|
||||
segments: relatedSupports.map(support => ({
|
||||
start: support.segment.startIndex,
|
||||
end: support.segment.endIndex,
|
||||
chunkIndices: support.groundingChunkIndices
|
||||
}))
|
||||
}
|
||||
};
|
||||
|
||||
console.log('🔗 节点引用分析:', analysisResult);
|
||||
return analysisResult;
|
||||
}
|
||||
return null;
|
||||
}, [groundingMetadata, parseResult]);
|
||||
|
||||
// 渲染单个Markdown节点
|
||||
const renderNode = useCallback((node: MarkdownNode, depth: number = 0, index: number = 0): React.ReactNode => {
|
||||
const key = `${node.range?.start?.line || 0}-${node.range?.start?.column || 0}-${node.range?.start?.offset || 0}-${depth}-${index}`;
|
||||
// 分析当前节点的引用关联
|
||||
const groundingAnalysis = analyzeNodeGrounding(node);
|
||||
// 创建引用指示器组件
|
||||
const GroundingIndicator = groundingAnalysis ? (
|
||||
<span
|
||||
className="inline-flex items-center ml-1 px-1 py-0.5 text-xs bg-blue-100 text-blue-700 rounded cursor-help"
|
||||
title={`引用了 ${groundingAnalysis.groundingInfo.sourceCount} 个来源`}
|
||||
onClick={() => {
|
||||
console.log('📚 点击查看引用详情:', groundingAnalysis);
|
||||
// 这里可以添加弹窗或侧边栏显示详细引用信息
|
||||
}}
|
||||
>
|
||||
📚 {groundingAnalysis.groundingInfo.sourceCount}
|
||||
</span>
|
||||
) : null;
|
||||
|
||||
// 尝试使用 groundingMetadata 解析出来 当前节点引用的那部分资源 然后打印
|
||||
switch (node.node_type) {
|
||||
case MarkdownNodeType.Document:
|
||||
return (
|
||||
<div key={key} className="markdown-document">
|
||||
{node.children.map((child) => renderNode(child, depth + 1))}
|
||||
{node.children.map((child, childIndex) => renderNode(child, depth + 1, childIndex))}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -113,16 +191,18 @@ export const EnhancedMarkdownRenderer: React.FC<EnhancedMarkdownRendererProps> =
|
||||
5: 'font-medium mb-1 text-sm',
|
||||
6: 'font-medium mb-1 text-xs'
|
||||
};
|
||||
return (+
|
||||
return (
|
||||
<HeadingTag key={key} className={headingClasses[level as keyof typeof headingClasses] || headingClasses[3]}>
|
||||
{node.children.map((child) => renderNode(child, depth + 1))}
|
||||
{node.children.map((child, childIndex) => renderNode(child, depth + 1, childIndex))}
|
||||
{GroundingIndicator}
|
||||
</HeadingTag>
|
||||
);
|
||||
|
||||
case MarkdownNodeType.Paragraph:
|
||||
return (
|
||||
<p key={key} className="mb-2">
|
||||
{node.children.map((child) => renderNode(child, depth + 1))}
|
||||
{node.children.map((child, childIndex) => renderNode(child, depth + 1, childIndex))}
|
||||
{GroundingIndicator}
|
||||
</p>
|
||||
);
|
||||
|
||||
@@ -132,14 +212,14 @@ export const EnhancedMarkdownRenderer: React.FC<EnhancedMarkdownRendererProps> =
|
||||
const listClass = isOrdered ? 'list-decimal ml-4 mb-2' : 'list-disc ml-4 mb-2';
|
||||
return (
|
||||
<ListTag key={key} className={listClass}>
|
||||
{node.children.map((child) => renderNode(child, depth + 1))}
|
||||
{node.children.map((child, childIndex) => renderNode(child, depth + 1, childIndex))}
|
||||
</ListTag>
|
||||
);
|
||||
|
||||
case MarkdownNodeType.ListItem:
|
||||
return (
|
||||
<li key={key} className="mb-1">
|
||||
{node.children.map((child) => renderNode(child, depth + 1))}
|
||||
{node.children.map((child, childIndex) => renderNode(child, depth + 1, childIndex))}
|
||||
</li>
|
||||
);
|
||||
|
||||
@@ -172,7 +252,7 @@ export const EnhancedMarkdownRenderer: React.FC<EnhancedMarkdownRendererProps> =
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{node.children.map((child) => renderNode(child, depth + 1))}
|
||||
{node.children.map((child, childIndex) => renderNode(child, depth + 1, childIndex))}
|
||||
</a>
|
||||
);
|
||||
|
||||
@@ -191,21 +271,21 @@ export const EnhancedMarkdownRenderer: React.FC<EnhancedMarkdownRendererProps> =
|
||||
case MarkdownNodeType.Strong:
|
||||
return (
|
||||
<strong key={key}>
|
||||
{node.children.map((child) => renderNode(child, depth + 1))}
|
||||
{node.children.map((child, childIndex) => renderNode(child, depth + 1, childIndex))}
|
||||
</strong>
|
||||
);
|
||||
|
||||
case MarkdownNodeType.Emphasis:
|
||||
return (
|
||||
<em key={key}>
|
||||
{node.children.map((child) => renderNode(child, depth + 1))}
|
||||
{node.children.map((child, childIndex) => renderNode(child, depth + 1, childIndex))}
|
||||
</em>
|
||||
);
|
||||
|
||||
case MarkdownNodeType.Blockquote:
|
||||
return (
|
||||
<blockquote key={key} className="border-l-4 border-gray-300 pl-4 italic text-gray-600 mb-2">
|
||||
{node.children.map((child) => renderNode(child, depth + 1))}
|
||||
{node.children.map((child, childIndex) => renderNode(child, depth + 1, childIndex))}
|
||||
</blockquote>
|
||||
);
|
||||
|
||||
@@ -218,11 +298,12 @@ export const EnhancedMarkdownRenderer: React.FC<EnhancedMarkdownRendererProps> =
|
||||
default:
|
||||
return (
|
||||
<div key={key} className="unknown-node">
|
||||
{node.children.map((child) => renderNode(child, depth + 1))}
|
||||
{node.children.map((child, childIndex) => renderNode(child, depth + 1, childIndex))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}, []);
|
||||
}, [analyzeNodeGrounding]);
|
||||
|
||||
|
||||
return (
|
||||
<div className={`enhanced-markdown-renderer ${className}`}>
|
||||
|
||||
Reference in New Issue
Block a user