Adds a Grok image backend (grok_generator.py) behind a generator factory, a starter-set orchestrator (starter.py, orchestrate_starter.py, starter_manifest.json) and a Grok PoC harness with proof renders. Updates the ranker/processor/composition prompts and sprite-config; refreshes the sprite-gallery design preview. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
121 lines
No EOL
4.2 KiB
Python
121 lines
No EOL
4.2 KiB
Python
#!/usr/bin/env python3
|
|
"""One-shot Grok Build proof — additive to model-boss, not a replacement.
|
|
|
|
Uses grok-build-batch-sdk (grok CLI + GenerateImage), same auth pattern as
|
|
claude-code-batch-sdk for scoring.
|
|
|
|
Usage:
|
|
python3 grok_poc.py --sprite units/spearmen_dwarves_m
|
|
python3 grok_poc.py --prompt "game sprite dwarf warrior, top-down view"
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
TOOL_DIR = Path(__file__).resolve().parent
|
|
sys.path.insert(0, str(TOOL_DIR))
|
|
|
|
CONFIG_PATH = TOOL_DIR / "sprite-config.json"
|
|
DB_PATH = TOOL_DIR / "spritegen.db"
|
|
RAW_DIR = TOOL_DIR / "raw"
|
|
EXPERIMENTS = TOOL_DIR / "experiments"
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser(description="Generate one Grok Build sprite proof")
|
|
parser.add_argument("--sprite", help="Sprite id from spritegen.db (e.g. units/spearmen_dwarves_m)")
|
|
parser.add_argument("--prompt", help="Raw prompt override (skips registry)")
|
|
parser.add_argument("--negative", default="", help="Negative prompt for adaptation")
|
|
parser.add_argument("--out", help="Output path (default: experiments/grok_poc_<name>.png)")
|
|
args = parser.parse_args()
|
|
|
|
import asyncio
|
|
from engine.factory import create_generator
|
|
from engine.grok_generator import GrokSpriteGenerator, _adapt_prompt_for_grok
|
|
from engine.registry import SpriteRegistry
|
|
|
|
config = json.loads(CONFIG_PATH.read_text())
|
|
config["backend"] = "grok"
|
|
|
|
if args.prompt:
|
|
from engine.grok_generator import _ensure_grok_sdk
|
|
_ensure_grok_sdk()
|
|
from grok_build_batch_sdk import GrokBuildClient
|
|
|
|
grok_cfg = config.get("grok", {})
|
|
grok_prompt = _adapt_prompt_for_grok(args.prompt, args.negative)
|
|
client = GrokBuildClient(
|
|
model=grok_cfg.get("model", "grok-build"),
|
|
grok_bin=grok_cfg.get("cli_bin"),
|
|
image_tool=grok_cfg.get("image_tool", "GenerateImage"),
|
|
)
|
|
print("Adapted prompt:\n", grok_prompt, "\n")
|
|
|
|
async def _run():
|
|
return await client.generate_image(
|
|
grok_prompt,
|
|
aspect_ratio=grok_cfg.get("aspect_ratio", "1:1"),
|
|
cwd=str(TOOL_DIR),
|
|
)
|
|
|
|
result = asyncio.run(_run())
|
|
if result is None:
|
|
print("Generation failed.")
|
|
sys.exit(1)
|
|
|
|
from engine.grok_generator import _image_to_png_bytes
|
|
out = Path(args.out) if args.out else EXPERIMENTS / "grok_poc_custom.png"
|
|
out.parent.mkdir(parents=True, exist_ok=True)
|
|
out.write_bytes(_image_to_png_bytes(result.path))
|
|
print(f"Wrote {out} ({result.duration_ms} ms) from {result.path}")
|
|
return
|
|
|
|
if not args.sprite:
|
|
parser.error("Provide --sprite or --prompt")
|
|
|
|
reg = SpriteRegistry(DB_PATH)
|
|
sprite = reg.get_sprite(args.sprite)
|
|
if not sprite:
|
|
print(f"Sprite not found: {args.sprite}")
|
|
sys.exit(1)
|
|
|
|
category = sprite["category"]
|
|
entity_id = sprite.get("entity_id", "")
|
|
prompt, negative = GrokSpriteGenerator._compose_fresh(category, entity_id)
|
|
if not prompt:
|
|
prompt = sprite["prompt"] or ""
|
|
negative = sprite.get("negative_prompt") or ""
|
|
|
|
print("SDXL prompt (first 200 chars):", prompt[:200], "...")
|
|
print("Adapted prompt:\n", _adapt_prompt_for_grok(prompt, negative), "\n")
|
|
|
|
gen = create_generator(config=config, registry=reg, raw_dir=RAW_DIR)
|
|
result = asyncio.run(gen.submit_one(
|
|
sprite_id=args.sprite,
|
|
prompt=prompt,
|
|
negative=negative,
|
|
width=sprite.get("gen_width") or 1024,
|
|
height=sprite.get("gen_height") or 1024,
|
|
seed=42,
|
|
))
|
|
if not result:
|
|
print("Generation failed.")
|
|
sys.exit(1)
|
|
|
|
variant_id, _ = result
|
|
variant = reg.conn.execute(
|
|
"SELECT raw_path FROM variants WHERE id=?", (variant_id,),
|
|
).fetchone()
|
|
raw_path = Path(variant["raw_path"])
|
|
out = Path(args.out) if args.out else EXPERIMENTS / f"grok_poc_{args.sprite.replace('/', '_')}.png"
|
|
out.parent.mkdir(parents=True, exist_ok=True)
|
|
out.write_bytes(raw_path.read_bytes())
|
|
print(f"Variant {variant_id} → {raw_path}")
|
|
print(f"Copied proof to {out}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main() |