{
  "version": "1.0",
  "kind": "flowith.canvas",
  "name": "Research Canvas — Cross-Source Brief",
  "description": "Seed a topic, scrape 8-12 sources, extract claims, dedupe by entity, then draft a one-pager. Designed for Flowith Pro multi-agent canvas.",
  "variables": {
    "TOPIC": "The state of AI voice agents in 2026",
    "SOURCE_LIMIT": 12,
    "OUTPUT_LANG": "en"
  },
  "nodes": [
    {
      "id": "seed",
      "type": "input",
      "label": "Topic seed",
      "value": "${TOPIC}"
    },
    {
      "id": "search",
      "type": "agent",
      "label": "Source finder",
      "model": "gpt-4.1-mini",
      "prompt": "Find ${SOURCE_LIMIT} high-quality sources about: {{seed}}. Diverse: include 1 academic, 1 industry report, 3 news, 3 vendor blogs, the rest mixed. Return JSON array of {title, url, source_type, published_at}."
    },
    {
      "id": "scrape",
      "type": "agent",
      "label": "Scrape + clean",
      "model": "gpt-4.1-mini",
      "prompt": "For each URL in {{search}}, fetch the page text, strip nav/footer, return {url, plain_text} array. Skip if 403/404."
    },
    {
      "id": "claims",
      "type": "agent",
      "label": "Claim extractor",
      "model": "gpt-4.1",
      "prompt": "From each cleaned doc in {{scrape}}, extract atomic factual claims as {claim, source_url, confidence}. Skip opinions. Return one flat array."
    },
    {
      "id": "dedupe",
      "type": "agent",
      "label": "Dedupe + cluster",
      "model": "gpt-4.1",
      "prompt": "Cluster {{claims}} by entity + topic. Within each cluster, mark agreements and contradictions. Return {clusters: [{entity, topic, agreed: [...], contested: [...]}]}."
    },
    {
      "id": "brief",
      "type": "agent",
      "label": "One-pager draft",
      "model": "gpt-4.1",
      "prompt": "Write a 700-word executive brief on '{{seed}}' using {{dedupe}}. Lead with the strongest agreed claims, surface 2-3 contradictions explicitly, and end with what's still uncertain. Cite source_url inline. Output Markdown."
    },
    {
      "id": "out",
      "type": "output",
      "label": "Brief Markdown",
      "value": "{{brief}}"
    }
  ],
  "edges": [
    {"from": "seed",   "to": "search"},
    {"from": "search", "to": "scrape"},
    {"from": "scrape", "to": "claims"},
    {"from": "claims", "to": "dedupe"},
    {"from": "dedupe", "to": "brief"},
    {"from": "brief",  "to": "out"}
  ]
}
