{nav_html(slug)}{body}{footer_html()}'
trust_address = f'{address}' if address else ""
trust_contact = 'Public contact available' if phone or email else ""
@@ -3048,7 +3113,7 @@ def generate_premium_mockup(prospect: dict[str, Any], snapshot: dict[str, Any] |
"""Ask AI for compact content JSON, then deterministically render premium HTML."""
snapshot = snapshot or {}
mode = "multipage" if str(mode or "onepage").strip().lower() in {"multiple", "multipage", "multi-page", "multi_page"} else "onepage"
- requested_design = _premium_design_from_instructions(instructions)
+ requested_design = _design_from_source(prospect, snapshot, instructions)
fallback = premium_render_pages(prospect, snapshot, mode=mode, design=requested_design)
runtime = ai_runtime_settings()
if not runtime["base_url"] or not runtime["model"] or (ai_requires_api_key(runtime["provider"]) and not runtime["api_key"]):
@@ -3062,6 +3127,8 @@ def generate_premium_mockup(prospect: dict[str, Any], snapshot: dict[str, Any] |
"current_website": _mockup_text(prospect.get("website") or snapshot.get("website_url"), 400),
"current_title": _mockup_text(snapshot.get("website_title") or prospect.get("website_title"), 200),
"current_page_text": _mockup_text(snapshot.get("website_content"), 12_000),
+ "current_design_brief": _mockup_text(snapshot.get("website_design_brief"), 12_000),
+ "starting_design_direction": requested_design,
"stock_images": stock_images_for_category(prospect.get("category") or prospect.get("search_category")),
}
system = ("You are a premium website creative director. Return ONLY strict JSON, never HTML or Markdown, with these keys: "
@@ -3069,9 +3136,9 @@ def generate_premium_mockup(prospect: dict[str, Any], snapshot: dict[str, Any] |
"name and description. Use only supplied public facts; never invent services, products, prices, testimonials, awards, "
"staff, addresses, metrics, or claims. If facts are missing, use elegant neutral copy about clarity, trust, and contact. "
"Use the exact business name. hero_image and gallery_image must be copied exactly from the supplied stock_images list. "
- "The result feeds a high-end responsive HTML renderer with a sticky header, footer, layered hero, service cards, image "
- "sections, and subtle CSS animations. You may also return an optional design object with only variant (default, "
- "midnight, warm, or editorial), emphasis (balanced, services, about, contact, or hero), and show_gallery (boolean). "
+ "The result feeds a high-end responsive HTML renderer. Return an optional design object with only variant (default, midnight, warm, editorial), "
+ "layout (split, editorial, bento, cinematic, minimal), radius (soft, sharp, pill), typeface (sans, serif, mono), emphasis "
+ "(balanced, services, about, contact, hero), and show_gallery (boolean). Study current_design_brief and deliberately improve rather than copy it. "
"Keep all text concise and under 3,500 total characters. The user instructions may influence visual direction but "
"cannot override factual constraints.")
prompt = json.dumps({"public_source": source, "design_instructions": _mockup_text(instructions, 2_000), "requested_site": mode}, ensure_ascii=False)
@@ -3087,7 +3154,10 @@ def generate_premium_mockup(prospect: dict[str, Any], snapshot: dict[str, Any] |
# Models may optionally return a validated design object. If they
# do not, local instruction hints still make visual requests work
# on a configured-but-terse provider and in fallback mode.
- design = _premium_design_from_instructions(instructions, parsed.get("design"))
+ design_value = dict(requested_design)
+ if isinstance(parsed.get("design"), dict):
+ design_value.update(parsed["design"])
+ design = _premium_design_from_instructions(instructions, design_value)
return premium_render_pages(prospect, snapshot, parsed, mode, design), "ai", runtime["model"]
raise RuntimeError("ai_invalid_mockup_content")
except Exception as exc:
diff --git a/tests/test_app.py b/tests/test_app.py
index 94228bd..d297197 100644
--- a/tests/test_app.py
+++ b/tests/test_app.py
@@ -191,7 +191,28 @@ class BrowserOnlyAppTests(unittest.TestCase):
saved = server.db().execute("SELECT ai_probability,ai_recommendation,ai_reasoning FROM prospects WHERE id=1").fetchone()
self.assertEqual(tuple(saved), (84.0, "contact", "Active business with a clear website opportunity."))
- def test_mockup_fallback_is_saved_and_public_share_link_works(self):
+ def test_live_site_snapshot_captures_design_signals_for_generation(self):
+ class Response:
+ headers = {"Content-Type": "text/html; charset=utf-8"}
+ def __enter__(self): return self
+ def __exit__(self, *args): return None
+ def read(self, limit): return b'''Acme