Download constraint_graph_svg.py from Snapkitty/sovereign-xml-compiler: direct link, hf CLI and curl.
- Browser
- Download file 7.77 kB
-
https://huggingface.co/Snapkitty/sovereign-xml-compiler/resolve/main/constraint_graph_svg.py
- Command line
-
hf download hf://Snapkitty/sovereign-xml-compiler/constraint_graph_svg.py
-
curl -L -o constraint_graph_svg.py https://huggingface.co/Snapkitty/sovereign-xml-compiler/resolve/main/constraint_graph_svg.py
7.77 kB
| """ | |
| constraint_graph_svg.py β Ahmad's ConstraintGraph compiler extension | |
| Compiles ConstraintGraph XML to both SVG visualization and executable runtime dict. | |
| """ | |
| import xml.etree.ElementTree as ET | |
| from collections import defaultdict, deque | |
| from typing import List, Dict, Any | |
| # βββ Node type emoji icons ββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| NODE_ICONS = { | |
| "Input": "\U0001f9e0", # π§ | |
| "Memory": "\U0001f4da", # π | |
| "Retrieval": "\U0001f50d", # π | |
| "Transform": "β", # β | |
| "Constraint": "β", # β | |
| "Proof": "\U0001f510", # π | |
| "Output": "\U0001f310", # π | |
| } | |
| # βββ SVG layout constants βββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| CANVAS_W = 400 | |
| CANVAS_H = 600 | |
| NODE_W = 160 | |
| NODE_H = 40 | |
| NODE_RX = 8 | |
| CENTER_X = 200 | |
| def _node_top_y(index: int, total: int) -> int: | |
| """Return the y-coordinate of the top edge of node at position index.""" | |
| margin_top = 30 | |
| spacing = (CANVAS_H - margin_top - NODE_H) // max(total - 1, 1) | |
| return margin_top + index * spacing | |
| # βββ Topological sort (Kahn's algorithm) βββββββββββββββββββββββββββββββββββββ | |
| def _topological_sort(nodes: List[dict], edges: List[dict]) -> List[str]: | |
| in_degree: Dict[str, int] = {n["id"]: 0 for n in nodes} | |
| adjacency: Dict[str, List[str]] = defaultdict(list) | |
| for e in edges: | |
| adjacency[e["from"]].append(e["to"]) | |
| in_degree[e["to"]] += 1 | |
| queue = deque(nid for nid, deg in in_degree.items() if deg == 0) | |
| order = [] | |
| while queue: | |
| nid = queue.popleft() | |
| order.append(nid) | |
| for neighbor in adjacency[nid]: | |
| in_degree[neighbor] -= 1 | |
| if in_degree[neighbor] == 0: | |
| queue.append(neighbor) | |
| if len(order) != len(nodes): | |
| raise ValueError("ConstraintGraph contains a cycle β topological sort failed.") | |
| return order | |
| # βββ XML parsing βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def _parse_graph_xml(xml_source: str): | |
| root = ET.fromstring(xml_source) | |
| if root.tag != "graph": | |
| raise ValueError(f"Root element must be <graph>, got <{root.tag}>") | |
| nodes = [] | |
| edges = [] | |
| for child in root: | |
| if child.tag == "node": | |
| nodes.append({"id": child.attrib["id"], "type": child.attrib["type"]}) | |
| elif child.tag == "edge": | |
| edges.append({"from": child.attrib["from"], "to": child.attrib["to"]}) | |
| return nodes, edges | |
| # βββ SVG renderer ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def _render_svg(nodes: List[dict], edges: List[dict], pipeline: List[str]) -> str: | |
| # Build index map: node id β position in pipeline | |
| pos_map = {nid: i for i, nid in enumerate(pipeline)} | |
| type_map = {n["id"]: n["type"] for n in nodes} | |
| total = len(pipeline) | |
| svg_lines = [ | |
| f'<svg xmlns="http://www.w3.org/2000/svg" ' | |
| f'width="{CANVAS_W}" height="{CANVAS_H}" ' | |
| f'viewBox="0 0 {CANVAS_W} {CANVAS_H}">', | |
| " <!-- ConstraintGraph SVG β generated by constraint_graph_svg.py -->", | |
| " <defs>", | |
| " <marker id=\"arrowhead\" markerWidth=\"10\" markerHeight=\"7\" " | |
| "refX=\"10\" refY=\"3.5\" orient=\"auto\">", | |
| " <polygon points=\"0 0, 10 3.5, 0 7\" fill=\"#444\"/>", | |
| " </marker>", | |
| " </defs>", | |
| ] | |
| # Compute node rects | |
| node_rects: Dict[str, dict] = {} | |
| for nid in pipeline: | |
| idx = pos_map[nid] | |
| x = CENTER_X - NODE_W // 2 | |
| y = _node_top_y(idx, total) | |
| node_rects[nid] = {"x": x, "y": y} | |
| # Draw edges first (behind nodes) | |
| for edge in edges: | |
| src = edge["from"] | |
| dst = edge["to"] | |
| if src not in node_rects or dst not in node_rects: | |
| continue | |
| sx = CENTER_X | |
| sy = node_rects[src]["y"] + NODE_H | |
| dx = CENTER_X | |
| dy = node_rects[dst]["y"] | |
| svg_lines.append( | |
| f' <line x1="{sx}" y1="{sy}" x2="{dx}" y2="{dy}" ' | |
| f'stroke="#444" stroke-width="2" marker-end="url(#arrowhead)"/>' | |
| ) | |
| # Draw nodes | |
| for nid in pipeline: | |
| node_type = type_map[nid] | |
| icon = NODE_ICONS.get(node_type, "?") | |
| x = node_rects[nid]["x"] | |
| y = node_rects[nid]["y"] | |
| label = f"{icon} {node_type}" | |
| cx = x + NODE_W // 2 | |
| cy = y + NODE_H // 2 + 5 # vertical center of text | |
| svg_lines.append( | |
| f' <rect x="{x}" y="{y}" width="{NODE_W}" height="{NODE_H}" ' | |
| f'rx="{NODE_RX}" fill="white" stroke="#333" stroke-width="1.5"/>' | |
| ) | |
| svg_lines.append( | |
| f' <text x="{cx}" y="{cy}" text-anchor="middle" ' | |
| f'font-family="sans-serif" font-size="13" fill="#111">' | |
| f'{label}</text>' | |
| ) | |
| svg_lines.append("</svg>") | |
| return "\n".join(svg_lines) | |
| # βββ ConstraintGraphCompiler ββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| class ConstraintGraphCompiler: | |
| """ | |
| Ahmad's ConstraintGraph compiler. | |
| Takes ConstraintGraph XML and compiles to: | |
| - SVG visualization (compile_to_svg) | |
| - Executable runtime dict (compile_to_runtime) | |
| """ | |
| def compile_to_svg(self, xml_source: str) -> str: | |
| """ | |
| Compile ConstraintGraph XML to an SVG string. | |
| Nodes are laid out vertically in topological order with arrowhead edges. | |
| """ | |
| nodes, edges = _parse_graph_xml(xml_source) | |
| pipeline = _topological_sort(nodes, edges) | |
| return _render_svg(nodes, edges, pipeline) | |
| def compile_to_runtime(self, xml_source: str) -> Dict[str, Any]: | |
| """ | |
| Compile ConstraintGraph XML to an executable runtime representation. | |
| Returns: | |
| { | |
| "nodes": [{"id": ..., "type": ...}, ...], | |
| "edges": [{"from": ..., "to": ...}, ...], | |
| "pipeline": [<topologically sorted node ids>] | |
| } | |
| """ | |
| nodes, edges = _parse_graph_xml(xml_source) | |
| pipeline = _topological_sort(nodes, edges) | |
| return { | |
| "nodes": nodes, | |
| "edges": edges, | |
| "pipeline": pipeline, | |
| } | |
| # βββ CLI ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def _cli(): | |
| import sys | |
| if len(sys.argv) < 2 or sys.argv[1] in ("-h", "--help"): | |
| print("Usage: constraint-graph <input.xml> [output.svg|--runtime]") | |
| print(" Compiles a <graph> XML to SVG or prints the runtime dict.") | |
| sys.exit(0) | |
| src = open(sys.argv[1], encoding="utf-8").read() | |
| compiler = ConstraintGraphCompiler() | |
| if len(sys.argv) >= 3 and sys.argv[2] == "--runtime": | |
| import json | |
| print(json.dumps(compiler.compile_to_runtime(src), indent=2)) | |
| else: | |
| svg = compiler.compile_to_svg(src) | |
| if len(sys.argv) >= 3: | |
| open(sys.argv[2], "w", encoding="utf-8").write(svg) | |
| else: | |
| print(svg) | |
| if __name__ == "__main__": | |
| _cli() | |