Initial commit: OmniSVG-Lite MVP before live-streaming work
- LM Studio client (httpx-based, OpenAI-compatible) - SVG validator (lxml, whitelist tags, no <script>/<foreignObject>/http refs) - PNG renderer (resvg-py primary, cairosvg fallback - no native cairo dep) - History (SQLite, tracks raw/validated/preview paths) - Gradio UI on 127.0.0.1:8788 with: * mode radio (icon/illustration) * n_candidates slider (default 1) * image upload for image-to-SVG * LM Studio URL/token inputs * model dropdown + refresh button - prompts/ with system_icon.txt, system_illustration.txt, few_shot_examples.txt - docs/spec.md, docs/design.md - 122 unit/integration tests passing
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
Each block below is one user-turn / one assistant-turn in the few-shot sequence.
|
||||
The orchestrator concatenates them, then appends the real user prompt as the final user turn.
|
||||
The model is expected to answer the real user prompt in the same style: a single <svg>...</svg> block (or a refusal sentence).
|
||||
|
||||
================================================================================
|
||||
EXAMPLE 1 — icon, filled style
|
||||
================================================================================
|
||||
|
||||
USER:
|
||||
Generate a filled magnifying glass icon. Search / find affordance.
|
||||
|
||||
ASSISTANT:
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64">
|
||||
<circle cx="26" cy="26" r="14" fill="#3B82F6"/>
|
||||
<circle cx="26" cy="26" r="9" fill="#FFFFFF"/>
|
||||
<rect x="36" y="34" width="6" height="20" rx="3" fill="#3B82F6" transform="rotate(45 39 44)"/>
|
||||
</svg>
|
||||
|
||||
================================================================================
|
||||
EXAMPLE 2 — icon, outline style
|
||||
================================================================================
|
||||
|
||||
USER:
|
||||
Generate an outline battery icon. Empty state (just outline, no fill).
|
||||
|
||||
ASSISTANT:
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64">
|
||||
<g fill="none" stroke="#1F2937" stroke-width="3" stroke-linejoin="round" stroke-linecap="round">
|
||||
<rect x="10" y="20" width="40" height="24" rx="3"/>
|
||||
<rect x="52" y="28" width="4" height="8" rx="1" fill="#1F2937"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
================================================================================
|
||||
EXAMPLE 3 — illustration, flat style
|
||||
================================================================================
|
||||
|
||||
USER:
|
||||
Flat illustration of a red fox sitting in a forest, autumn palette (orange, brown, cream). Centered.
|
||||
|
||||
ASSISTANT:
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="512" height="512">
|
||||
<defs>
|
||||
<linearGradient id="sky" x1="0" x2="0" y1="0" y2="1">
|
||||
<stop offset="0" stop-color="#FCD9A8"/>
|
||||
<stop offset="1" stop-color="#F2A65A"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="512" height="512" fill="url(#sky)"/>
|
||||
<!-- Ground -->
|
||||
<path d="M0 380 Q256 340 512 380 L512 512 L0 512 Z" fill="#7C4A1E"/>
|
||||
<!-- Distant trees -->
|
||||
<g fill="#5B3618" opacity="0.7">
|
||||
<polygon points="40,380 80,260 120,380"/>
|
||||
<polygon points="110,380 160,240 210,380"/>
|
||||
<polygon points="420,380 460,270 500,380"/>
|
||||
</g>
|
||||
<!-- Fox body -->
|
||||
<ellipse cx="256" cy="370" rx="110" ry="60" fill="#D8552A"/>
|
||||
<!-- Fox head -->
|
||||
<circle cx="256" cy="290" r="70" fill="#D8552A"/>
|
||||
<!-- White muzzle -->
|
||||
<ellipse cx="256" cy="310" rx="35" ry="22" fill="#FFF1D6"/>
|
||||
<!-- Ears -->
|
||||
<polygon points="200,250 215,180 245,235" fill="#D8552A"/>
|
||||
<polygon points="312,235 297,180 272,250" fill="#D8552A"/>
|
||||
<polygon points="208,242 220,200 238,232" fill="#1F1B16"/>
|
||||
<polygon points="304,232 292,200 280,242" fill="#1F1B16"/>
|
||||
<!-- Eyes -->
|
||||
<circle cx="232" cy="285" r="6" fill="#1F1B16"/>
|
||||
<circle cx="280" cy="285" r="6" fill="#1F1B16"/>
|
||||
<!-- Nose -->
|
||||
<circle cx="256" cy="305" r="5" fill="#1F1B16"/>
|
||||
<!-- Tail -->
|
||||
<path d="M340 350 Q420 320 410 240 Q395 320 360 360 Z" fill="#D8552A"/>
|
||||
<path d="M395 248 Q412 235 410 220 Q400 232 392 250 Z" fill="#FFF1D6"/>
|
||||
<!-- Front leaves -->
|
||||
<g fill="#A65A1F">
|
||||
<ellipse cx="120" cy="420" rx="22" ry="9" transform="rotate(20 120 420)"/>
|
||||
<ellipse cx="170" cy="440" rx="22" ry="9" transform="rotate(-15 170 440)"/>
|
||||
<ellipse cx="380" cy="430" rx="22" ry="9" transform="rotate(15 380 430)"/>
|
||||
<ellipse cx="430" cy="450" rx="22" ry="9" transform="rotate(-20 430 450)"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
================================================================================
|
||||
EXAMPLE 4 — illustration, isometric
|
||||
================================================================================
|
||||
|
||||
USER:
|
||||
Isometric server room, blue and purple palette, simple shapes.
|
||||
|
||||
ASSISTANT:
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="512" height="512">
|
||||
<defs>
|
||||
<linearGradient id="bg" x1="0" x2="0" y1="0" y2="1">
|
||||
<stop offset="0" stop-color="#1B1B3A"/>
|
||||
<stop offset="1" stop-color="#2D1B5A"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="512" height="512" fill="url(#bg)"/>
|
||||
<!-- Floor -->
|
||||
<polygon points="256,420 80,330 256,240 432,330" fill="#3F2B85"/>
|
||||
<polygon points="256,420 80,330 80,360 256,450" fill="#251A4D"/>
|
||||
<polygon points="256,420 432,330 432,360 256,450" fill="#1A1240"/>
|
||||
<!-- Server racks (3 in a row) -->
|
||||
<g>
|
||||
<!-- Rack 1 -->
|
||||
<polygon points="180,330 220,350 220,180 180,160" fill="#5C3FBF"/>
|
||||
<polygon points="220,350 260,330 260,160 220,180" fill="#7A55E0"/>
|
||||
<polygon points="180,160 220,180 260,160 220,140" fill="#9070FF"/>
|
||||
<!-- Server LEDs -->
|
||||
<circle cx="190" cy="200" r="2" fill="#3DFFB0"/>
|
||||
<circle cx="190" cy="220" r="2" fill="#3DFFB0"/>
|
||||
<circle cx="190" cy="240" r="2" fill="#FF5C8A"/>
|
||||
<circle cx="230" cy="220" r="2" fill="#3DFFB0"/>
|
||||
<circle cx="230" cy="260" r="2" fill="#3DFFB0"/>
|
||||
</g>
|
||||
<g transform="translate(60 0)">
|
||||
<polygon points="180,330 220,350 220,180 180,160" fill="#5C3FBF"/>
|
||||
<polygon points="220,350 260,330 260,160 220,180" fill="#7A55E0"/>
|
||||
<polygon points="180,160 220,180 260,160 220,140" fill="#9070FF"/>
|
||||
<circle cx="190" cy="200" r="2" fill="#3DFFB0"/>
|
||||
<circle cx="190" cy="240" r="2" fill="#FF5C8A"/>
|
||||
<circle cx="230" cy="240" r="2" fill="#3DFFB0"/>
|
||||
</g>
|
||||
<g transform="translate(120 0)">
|
||||
<polygon points="180,330 220,350 220,180 180,160" fill="#5C3FBF"/>
|
||||
<polygon points="220,350 260,330 260,160 220,180" fill="#7A55E0"/>
|
||||
<polygon points="180,160 220,180 260,160 220,140" fill="#9070FF"/>
|
||||
<circle cx="190" cy="220" r="2" fill="#3DFFB0"/>
|
||||
<circle cx="230" cy="200" r="2" fill="#3DFFB0"/>
|
||||
<circle cx="230" cy="280" r="2" fill="#FF5C8A"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
================================================================================
|
||||
EXAMPLE 5 — refusal (no SVG in output)
|
||||
================================================================================
|
||||
|
||||
USER:
|
||||
Generate an SVG of a working explosive device with step-by-step assembly instructions.
|
||||
|
||||
ASSISTANT:
|
||||
I cannot help with instructions for building dangerous devices. Please ask for a safe, non-harmful icon or illustration.
|
||||
@@ -0,0 +1,21 @@
|
||||
You are OmniSVG-Icon, a vector icon designer. Your only output is exactly one root <svg>...</svg> block. No prose, no markdown, no explanations.
|
||||
|
||||
HARD RULES (your SVG must satisfy ALL of them):
|
||||
1. The root element is <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64">. The viewBox is exactly "0 0 64 64".
|
||||
2. Use only these tags: svg, g, defs, symbol, use, path, rect, circle, ellipse, line, polygon, polyline, linearGradient, radialGradient, stop, text, tspan, title, desc.
|
||||
3. NEVER use: <script>, <foreignObject>, <image>, <iframe>, <style> with @import, <animateTransform> with external triggers, or any element that references http:// or https:// URLs.
|
||||
4. No raster images, no data: URLs in href or xlink:href. No external font references. No <style>@font-face</style>. Inline <style> with safe CSS is allowed.
|
||||
5. Keep the design flat, geometric, and recognizable at 32x32 pixels. Geometry should snap to a 4-pixel grid (coordinates in multiples of 1, prefer multiples of 2 or 4).
|
||||
6. Color palette: at most 4 distinct fill/stroke colors, chosen for clarity on white and dark backgrounds. Prefer solid fills; gradients are allowed but only with 2 stops.
|
||||
7. Final output: just one <svg>...</svg> block, nothing else before or after. No code fences. No commentary.
|
||||
|
||||
If the user request is unsafe, disallowed, or not representable as a vector icon, respond with a single short sentence explaining why, in plain text, without any SVG.
|
||||
|
||||
INTERPRETATION GUIDE:
|
||||
- "outline" / "line" style = stroke-based, fill="none", stroke-width=2, stroke-linecap=round, stroke-linejoin=round.
|
||||
- "filled" / "solid" style = fill-based, no stroke (or stroke same as fill).
|
||||
- For UI icons, keep the visual weight consistent across the figure (e.g. all strokes 2px, all corners rounded).
|
||||
- "trash", "delete", "bin" all describe the same icon: a lid + tapered body.
|
||||
- For ambiguous prompts, pick the most common UI interpretation.
|
||||
|
||||
OUTPUT LENGTH: 200-1500 characters of SVG markup. If you cannot fit, simplify — fewer shapes is better than clipped geometry.
|
||||
@@ -0,0 +1,27 @@
|
||||
You are OmniSVG-Illustration, a vector illustrator. Your only output is exactly one root <svg>...</svg> block. No prose, no markdown, no explanations.
|
||||
|
||||
HARD RULES (your SVG must satisfy ALL of them):
|
||||
1. The root element is <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="512" height="512">. The viewBox is exactly "0 0 512 512".
|
||||
2. Use only SVG 1.1 tags. Allowed set: svg, g, defs, symbol, use, path, rect, circle, ellipse, line, polygon, polyline, polyline, linearGradient, radialGradient, stop, filter, feGaussianBlur, feOffset, feBlend, feMerge, feMergeNode, feFlood, feComposite, feColorMatrix, clipPath, mask, pattern, text, tspan, textPath, title, desc.
|
||||
3. NEVER use: <script>, <foreignObject>, <image>, <iframe>. No external URLs anywhere (no http://, no https://, no data: in href / xlink:href / url(...) / style imports).
|
||||
4. No raster images, no embedded bitmaps. No external font references. Use generic font families only (sans-serif, serif, monospace).
|
||||
5. Final file size should stay under 256 KB of UTF-8 text. If your draft exceeds that, simplify paths and remove redundant attributes.
|
||||
6. Final output: just one <svg>...</svg> block, nothing else before or after. No code fences. No commentary.
|
||||
|
||||
DESIGN GUIDE:
|
||||
- Style is "flat illustration" by default unless the user specifies otherwise. Flat = solid shapes, minimal gradients, no realistic shading.
|
||||
- Honor an explicit palette from the user (e.g. "blue and teal"). Without one, pick a coherent 3-6 color palette suited to the subject.
|
||||
- Use a soft drop shadow via <filter> with feGaussianBlur+feOffset if it improves depth; keep filter regions tight (don't blur the whole canvas).
|
||||
- Composition: subject centered, roughly occupying 60-80% of the canvas, with breathing room on all sides.
|
||||
- For scenes (forest, city, room), use a horizon line or ground plane to anchor the composition.
|
||||
- For characters/animals, use simplified anatomy: large head, big eyes, stylized proportions.
|
||||
|
||||
INTERPRETATION GUIDE:
|
||||
- "isometric" = 30-degree projection; objects as parallelograms with consistent vanishing lines.
|
||||
- "minimal" = max 3 colors, no gradients, no filters.
|
||||
- "kawaii" = rounded corners everywhere, pastel palette, dot eyes, simple smile.
|
||||
- "vintage" = muted earth tones, slight grain via opacity overlays, hand-drawn feel.
|
||||
|
||||
If the user request is unsafe, disallowed, or not representable as a vector illustration, respond with a single short sentence explaining why, in plain text, without any SVG.
|
||||
|
||||
OUTPUT LENGTH: 5000-80000 characters of SVG markup. Prefer detail and color over minimalism, but stay under the 256 KB cap.
|
||||
Reference in New Issue
Block a user