+ {preview.pages.map((page, i) => (
+
+
+ {page.name || t('chat.previewVisioPage').replace('{n}', String(i + 1))}
+
+ {page.svg ? (
+
+ ) : (
+
+ {page.text}
+
+ )}
+
+ ))}
+
+ {preview.hint || t('chat.previewVisioHint')}
+
+
+ )}
);
diff --git a/frontend/lib/artifacts.selftest.ts b/frontend/lib/artifacts.selftest.ts
index 24e3bf4b..24ea341b 100644
--- a/frontend/lib/artifacts.selftest.ts
+++ b/frontend/lib/artifacts.selftest.ts
@@ -27,4 +27,7 @@ const arts = extractArtifacts({
assert(arts.some((a) => a.name.includes('report') || a.path.includes('report')), 'md link');
assert(arts.some((a) => a.path.includes('hello.md')), 'tool path');
assert(arts.some((a) => a.kind === 'table'), 'table kind');
+
+const visio = extractArtifacts({ content: '见 docs/网络拓扑.vsd 以及 flow.vsdx' });
+assert(visio.some((a) => a.kind === 'visio'), 'visio kind');
console.log('artifacts.selftest OK', arts.length, arts.map((a) => a.name).join(', '));
diff --git a/frontend/lib/artifacts.ts b/frontend/lib/artifacts.ts
index 8358bf37..085b7a41 100644
--- a/frontend/lib/artifacts.ts
+++ b/frontend/lib/artifacts.ts
@@ -8,7 +8,7 @@ export interface ChatArtifact {
name: string;
source: 'tool' | 'content' | 'link';
/** 可选 mime 提示 */
- kind?: 'image' | 'table' | 'text' | 'pdf' | 'html' | 'markdown' | 'docx' | 'pptx' | 'other';
+ kind?: 'image' | 'table' | 'text' | 'pdf' | 'html' | 'markdown' | 'docx' | 'pptx' | 'visio' | 'other';
}
const WRITE_TOOLS = new Set([
@@ -53,6 +53,10 @@ const EXT_KIND: Record