mirror of
https://github.com/DayuanJiang/next-ai-draw-io.git
synced 2026-10-12 20:49:53 +08:00
feat(diagram): named styles the model defines once and uses by name
The model may now write <mxStyle name="step" value="..."/> before its cells and refer to the name inside a cell's style, the way draw.io resolves its own named styles. style-classes.ts expands the names after validation (so repaired cells get them too) and adds draw.io's defaults html=1 and whiteSpace=wrap where they belong, so the prompts can tell the model never to write them. Wired into display_diagram, append_diagram, create_new_diagram, add_page, edit_diagram (defaults only) and the streaming preview. Prompts (system prompt, tool description, MCP drawing guide) teach the notation with a shared example, drop the draw.io defaults from every example and tell the model how labels, line breaks and reserved names work. Measured on the five start-screen examples, same model and prompt, old vs new prompt: gpt-6-luna 19% fewer output tokens, Opus 5.5 19% fewer; flow and architecture diagrams 15% to 46%, creative drawings about equal.
This commit is contained in:
@@ -12,6 +12,12 @@ import {
|
||||
} from "@/lib/utils"
|
||||
import { applyDiagramOperations } from "@/packages/mcp-server/src/diagram-operations.ts"
|
||||
import { BLANK_MXFILE } from "@/packages/mcp-server/src/pages.ts"
|
||||
import {
|
||||
addDefaultStyles,
|
||||
applyStyleClasses,
|
||||
edgeIdsOf,
|
||||
readStyleClasses,
|
||||
} from "@/packages/mcp-server/src/style-classes.ts"
|
||||
|
||||
// Helper to extract complete operations from streaming input
|
||||
function getCompleteOperations(
|
||||
@@ -71,9 +77,14 @@ export function useDiagramStreaming({
|
||||
// so far. The tool handler validates and loads the final diagram.
|
||||
const handleDisplayChart = useCallback(
|
||||
(xml: string) => {
|
||||
const completeCells = extractCompleteMxCells(xml || "")
|
||||
// Named styles come before the cells, so the ones written so
|
||||
// far are known by the time their cells stream in
|
||||
const { classes, xml: cellsXml } = readStyleClasses(xml || "")
|
||||
const completeCells = extractCompleteMxCells(cellsXml)
|
||||
if (!completeCells) return
|
||||
const convertedXml = convertToLegalXml(completeCells)
|
||||
const convertedXml = addDefaultStyles(
|
||||
applyStyleClasses(convertToLegalXml(completeCells), classes),
|
||||
)
|
||||
if (convertedXml === previousXML.current) return
|
||||
|
||||
// Skip this update while the cells written so far don't parse
|
||||
@@ -202,9 +213,17 @@ export function useDiagramStreaming({
|
||||
if (lastProcessedXmlRef.current.get(opsKey) === ops) continue
|
||||
lastProcessedXmlRef.current.set(opsKey, ops)
|
||||
try {
|
||||
const edges = edgeIdsOf(originalXml)
|
||||
const { result } = applyDiagramOperations(
|
||||
originalXml,
|
||||
completeOps,
|
||||
completeOps.map((op) =>
|
||||
op.new_xml
|
||||
? {
|
||||
...op,
|
||||
new_xml: addDefaultStyles(op.new_xml, edges),
|
||||
}
|
||||
: op,
|
||||
),
|
||||
)
|
||||
if (lastProcessedXmlRef.current.get(resultKey) === result) {
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user