Phase 4.1+: mermaid diagrams + YAML workflow buttons + agents API (v2026.07.19.11)
CI / gate (push) Has been cancelled
CI / gate (push) Has been cancelled
This commit is contained in:
1 parent
79c27795a8
commit
72d6f9ab66
5 files changed
+1018
-35
No files matched your search
@@ -894,6 +894,9 @@ export const adminAPI = {
|
|||||||
// Phase 3.3: 多 Agent 编排图 (orchestration)
|
// Phase 3.3: 多 Agent 编排图 (orchestration)
|
||||||
getAgentOrchestration: (id: string) => get<any>(`/admin/agents/${id}/orchestration`),
|
getAgentOrchestration: (id: string) => get<any>(`/admin/agents/${id}/orchestration`),
|
||||||
setAgentOrchestration: (id: string, orchestration: any) => put<any>(`/admin/agents/${id}/orchestration`, { orchestration }),
|
setAgentOrchestration: (id: string, orchestration: any) => put<any>(`/admin/agents/${id}/orchestration`, { orchestration }),
|
||||||
|
importYamlOrch: (id: string, yaml: string) => post<any>(`/admin/agents/${id}/orchestration/yaml/import`, { yaml_text: yaml }),
|
||||||
|
exportYamlOrch: (id: string) => post<any>(`/admin/agents/${id}/orchestration/yaml/export`),
|
||||||
|
getYamlTemplates: () => get<any>('/admin/agents/orchestration/yaml/templates'),
|
||||||
|
|
||||||
getAdminAvailableSkills: (params?: any) => {
|
getAdminAvailableSkills: (params?: any) => {
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
@@ -519,6 +519,22 @@
|
|||||||
padding: 0 2px;
|
padding: 0 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mermaid 图表 */
|
||||||
|
.md-mermaid {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 16px 0;
|
||||||
|
padding: 12px;
|
||||||
|
background: #f8f9fb;
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
.md-mermaid-rendered svg {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
/* 代码块包装器 + 复制按钮 */
|
/* 代码块包装器 + 复制按钮 */
|
||||||
.md-code-wrapper {
|
.md-code-wrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ import hljs from 'highlight.js';
|
|||||||
import 'highlight.js/styles/github.css';
|
import 'highlight.js/styles/github.css';
|
||||||
import katex from 'katex';
|
import katex from 'katex';
|
||||||
import 'katex/dist/katex.min.css';
|
import 'katex/dist/katex.min.css';
|
||||||
|
import mermaid from 'mermaid';
|
||||||
|
|
||||||
|
mermaid.initialize({ startOnLoad: false, theme: 'default' });
|
||||||
|
|
||||||
// ===== Enhanced Markdown Renderer =====
|
// ===== Enhanced Markdown Renderer =====
|
||||||
// 媒体(图片/视频)以受限缩略图呈现,并提供下载(格式+尺寸)选项
|
// 媒体(图片/视频)以受限缩略图呈现,并提供下载(格式+尺寸)选项
|
||||||
@@ -155,7 +158,13 @@ const MarkdownContent: React.FC<{ content: string }> = ({ content }) => {
|
|||||||
|
|
||||||
// 1. Extract code blocks first (protect from other replacements)
|
// 1. Extract code blocks first (protect from other replacements)
|
||||||
const codeBlocks: string[] = [];
|
const codeBlocks: string[] = [];
|
||||||
|
const mermaidBlocks: string[] = [];
|
||||||
text = text.replace(/```(\w*)\n?([\s\S]*?)```/g, (_m: string, _lang: string, code: string) => {
|
text = text.replace(/```(\w*)\n?([\s\S]*?)```/g, (_m: string, _lang: string, code: string) => {
|
||||||
|
if (_lang === 'mermaid') {
|
||||||
|
const idx = mermaidBlocks.length;
|
||||||
|
mermaidBlocks.push('<div class="md-mermaid" data-code="' + escapeHtml(code.trim()) + '"></div>');
|
||||||
|
return '\x00MERMAID' + idx + '\x00';
|
||||||
|
}
|
||||||
const idx = codeBlocks.length;
|
const idx = codeBlocks.length;
|
||||||
codeBlocks.push('<pre class="md-code-block"><code class="md-code">' + escapeHtml(code.trim()) + '</code></pre>');
|
codeBlocks.push('<pre class="md-code-block"><code class="md-code">' + escapeHtml(code.trim()) + '</code></pre>');
|
||||||
return '\x00CODEBLOCK' + idx + '\x00';
|
return '\x00CODEBLOCK' + idx + '\x00';
|
||||||
@@ -275,6 +284,7 @@ const MarkdownContent: React.FC<{ content: string }> = ({ content }) => {
|
|||||||
|
|
||||||
// 10. Restore code blocks and inline codes
|
// 10. Restore code blocks and inline codes
|
||||||
text = text.replace(/\x00CODEBLOCK(\d+)\x00/g, (_m: string, idx: string) => codeBlocks[parseInt(idx)] || '');
|
text = text.replace(/\x00CODEBLOCK(\d+)\x00/g, (_m: string, idx: string) => codeBlocks[parseInt(idx)] || '');
|
||||||
|
text = text.replace(/\x00MERMAID(\d+)\x00/g, (_m: string, idx: string) => mermaidBlocks[parseInt(idx)] || '');
|
||||||
text = text.replace(/\x00INLINE(\d+)\x00/g, (_m: string, idx: string) => inlineCodes[parseInt(idx)] || '');
|
text = text.replace(/\x00INLINE(\d+)\x00/g, (_m: string, idx: string) => inlineCodes[parseInt(idx)] || '');
|
||||||
text = text.replace(/\x00TABLE(\d+)\x00/g, (_m: string, idx: string) => tableBlocks[parseInt(idx)] || '');
|
text = text.replace(/\x00TABLE(\d+)\x00/g, (_m: string, idx: string) => tableBlocks[parseInt(idx)] || '');
|
||||||
text = text.replace(/\x00MATHBLOCK(\d+)\x00/g, (_m: string, idx: string) => mathBlocks[parseInt(idx)] || '');
|
text = text.replace(/\x00MATHBLOCK(\d+)\x00/g, (_m: string, idx: string) => mathBlocks[parseInt(idx)] || '');
|
||||||
@@ -320,7 +330,29 @@ const MarkdownContent: React.FC<{ content: string }> = ({ content }) => {
|
|||||||
});
|
});
|
||||||
}, [content]);
|
}, [content]);
|
||||||
|
|
||||||
return <div className="markdown-body">{nodes}</div>;
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
|
useEffect(() => {
|
||||||
|
if (!containerRef.current) return;
|
||||||
|
const diagrams = containerRef.current.querySelectorAll('.md-mermaid:not(.md-mermaid-rendered)');
|
||||||
|
if (diagrams.length === 0) return;
|
||||||
|
const timer = setTimeout(async () => {
|
||||||
|
for (const el of diagrams) {
|
||||||
|
try {
|
||||||
|
const code = el.getAttribute('data-code') || '';
|
||||||
|
if (!code) continue;
|
||||||
|
const id = 'mermaid-' + Math.random().toString(36).slice(2, 10);
|
||||||
|
const { svg } = await mermaid.render(id, code);
|
||||||
|
el.innerHTML = svg;
|
||||||
|
el.classList.add('md-mermaid-rendered');
|
||||||
|
} catch (e) {
|
||||||
|
el.innerHTML = '<pre class="md-code-block"><code>Mermaid: ' + (e as Error).message + '</code></pre>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
|
return () => clearTimeout(timer);
|
||||||
|
}, [content]);
|
||||||
|
|
||||||
|
return <div className="markdown-body" ref={containerRef}>{nodes}</div>;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 解析后端返回的「模糊创作意图」确认指令:<<CLARIFY>>{json}<<CLARIFY>>
|
// 解析后端返回的「模糊创作意图」确认指令:<<CLARIFY>>{json}<<CLARIFY>>
|
||||||
|
|||||||
Reference in new issue
Block a user