LandingAgent is a multi-agent system that generates static landing pages from a target specification. It builds a Structured Page Brief, optionally retrieves reference page structure from a local corpus, drafts a wireframe, critiques it across design and messaging, and writes a final HTML bundle.
This repository is prepared as a source-only public release candidate. API keys, local configs, private research material, generated experiments, raw datasets, local synthetic image examples, and large qualitative outputs are intentionally excluded.
- Generates a complete static landing page from a JSON target specification and optional target images.
- Runs as a CLI, a Gradio web UI, or a Jupyter/Colab notebook.
- Supports retrieval-backed generation when a local reference corpus is available.
- Can run local synthetic demos without a corpus by using
--retrieval_setting none. - Saves intermediate agent artifacts so each generation step can be inspected.
LandingAgent/
agents/landing/ Landing-page agents and critics
prompts/landing/ Prompt templates for generation, critique, and evaluation
utils/ Runtime helpers, rendering, config, evaluation, and artifact IO
examples_synthetic/ Optional local synthetic demo briefs and target images (git-ignored)
notebooks/ End-to-end notebook workflow
configs/ Safe YAML templates only
docs/ Pipeline notes
app.py Gradio UI
main_landing.py CLI entry point
requirements.txt Python dependencies
- Python 3.10 or newer
- Playwright Chromium
- At least one supported model API key, usually
GOOGLE_API_KEYfor the default Gemini setup
Windows PowerShell:
python -m venv .venv
.\.venv\Scripts\activate
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
python -m playwright install chromiummacOS or Linux:
python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
python -m playwright install chromiumCopy the templates and fill only your local copies:
copy .env.example .env
copy configs\landing_config.template.yaml configs\landing_config.yaml
copy configs\model_config.template.yaml configs\model_config.yamlOn macOS or Linux:
cp .env.example .env
cp configs/landing_config.template.yaml configs/landing_config.yaml
cp configs/model_config.template.yaml configs/model_config.yamlUse .env for secrets:
GOOGLE_API_KEY=
ANTHROPIC_API_KEY=
OPENAI_API_KEY=
OPENROUTER_API_KEY=
Configuration files have separate roles:
.envis the preferred place for secrets such as API keys.configs/landing_config.yamlcontrols landing-pipeline defaults such as model names, corpus path, reference count, critic cycles, and optional provider/runtime settings.configs/model_config.yamlis an optional local provider/runtime override copied fromconfigs/model_config.template.yaml. Use it when you want API keys or local backend settings separate from the main landing pipeline config.
The actual .env, configs/landing_config.yaml, and configs/model_config.yaml files are git-ignored. Templates are safe to commit because they contain placeholders only.
Provider/runtime value precedence is:
.env / environment variables > configs/landing_config.yaml > configs/model_config.yaml
Model naming follows the paper terminology:
main_model_name: builds the page through the Profiler, Retriever, WireframeBuilder, and Polisher.critic_model_name: evaluates the page through the WireframeCritic, AestheticCritic, MessageCritic, and FunctionalCritic.multimodal_model_name: deprecated legacy alias. New configs should not set it.
If your local checkout still has examples_synthetic/, run a local synthetic example without a reference corpus:
python main_landing.py ^
--target_spec_path examples_synthetic\roomlyplay.json ^
--target_images_dir examples_synthetic\roomlyplay\target_images_synth ^
--output_dir results ^
--retrieval_setting noneEquivalent macOS or Linux command:
python main_landing.py \
--target_spec_path examples_synthetic/roomlyplay.json \
--target_images_dir examples_synthetic/roomlyplay/target_images_synth \
--output_dir results \
--retrieval_setting noneThe generated site is saved here:
results/<run_id>/final/index.html
Intermediate artifacts are saved under the same run directory, including the Structured Page Brief, retrieved references when enabled, wireframe HTML, screenshots, critic feedback, and final page assets.
If examples_synthetic/ is not present, create your own JSON brief and point --target_spec_path at it. A minimal brief looks like this:
{
"company_name": "ExampleCo",
"target_spec_body": "ExampleCo needs a clear landing page for a new productivity product. Emphasize the problem, core benefits, proof points, and one primary call to action. Do not invent customer logos, pricing, awards, or testimonials.",
"target_image_paths": []
}Then run with an empty or omitted image directory:
python main_landing.py \
--target_spec_path path/to/brief.json \
--target_images_dir path/to/images \
--output_dir results \
--retrieval_setting noneStart the Gradio app:
python app.pyThe UI can load local synthetic examples when examples_synthetic/ exists, accept a pasted brief or JSON brief, upload target images, run the full pipeline, and inspect intermediate outputs.
Open:
notebooks/LandingAgent_Colab_End_to_End.ipynb
The notebook can run from a local checkout or clone a public repository in Colab through REPO_URL or LANDINGAGENT_REPO_URL. It prompts for API keys at runtime and does not write them into the repository.
Retrieval-backed generation expects a corpus under:
data/LandingBench
That corpus is not part of this source release. Keep datasets and crawled assets outside the git repository, or distribute them separately. For source-only demos, use:
--retrieval_setting noneAvailable retrieval modes are:
auto, 2stage, manual, random, none
Useful local checks:
python -m compileall -q agents prompts utils app.py main_landing.py test_landing_agent.py
python -m json.tool notebooks/LandingAgent_Colab_End_to_End.ipynb
python -m pip check
python main_landing.py --helpFor single-agent smoke work, see:
python test_landing_agent.py --helpThe cleaned local copy was smoke-tested with the five local synthetic examples that were available during cleanup:
commerceshield, modkeep, portfoliospace, promptsong, roomlyplay
Those example assets are intentionally git-ignored, so they are not required for the public source tree. Full LLM execution still requires at least one configured provider API key.
- API keys and local configs:
.env,configs/landing_config.yaml,configs/model_config.yaml - Generated outputs:
results/,results_notebook/,experiment/ - Optional synthetic demos:
examples_synthetic/ - Full datasets, crawled assets, spreadsheets, archives, and benchmark bundles
- Internal research-share material, private slides, supplementary qualitative folders, and old notebooks
- Local virtual environments such as
.venv/
If you see a missing API key error, set GOOGLE_API_KEY in .env or fill the relevant key in configs/landing_config.yaml or configs/model_config.yaml.
If Playwright cannot render pages, run:
python -m playwright install chromiumIf the reference corpus is missing, either add your local corpus under data/LandingBench or run with --retrieval_setting none.
If the UI logs that the DINO sidecar could not load because torch is missing, core page generation is still usable. That sidecar is only needed for DINO-based diversity evaluation; install a compatible torch/transformers stack if you need those metrics.
This project is released under the Apache License 2.0. Some inherited utility files keep their original attribution headers. See LICENSE and NOTICE for details.