| name | ltx-leadership-weekly-report |
| description | Generate the LTX weekly leadership Slack post covering Open Source (HuggingFace LTX-2 family), API (revenue, endpoints, leads, industries), and Studio Enterprise (contracts, pilots, LTX-model consumption share). Runs every Monday via n8n: BigQuery → JSON parse → Slack render → LLM TL;DR → Slack webhook. Use when: weekly exec update, leadership Slack channel automation, or when asked for 'last week's LTX numbers'. |
| tags | ["reporting","weekly-metrics","ltx","oss","ltxvapi","ltxstudio","n8n","slack","leadership"] |
| compatibility | ["n8n self-hosted or cloud (workflow uses native BigQuery, Anthropic, and Slack nodes)","GCP project access (`ltx-dwh-prod-processed`) for the n8n BigQuery credential","Anthropic API key (Claude Sonnet 4.5 recommended) for the TL;DR node","Slack incoming webhook configured for the destination channel"] |
| metadata | {"author":"aheden","version":"1.0","created":"2026-05-06"} |
LTX Leadership Weekly Report
Overview
Weekly snapshot of LTX across all three product surfaces, posted every Monday morning to a leadership Slack channel:
- Open Source — HuggingFace download/likes momentum on LTX 2 / 2.3 / 2.3-fp8, plus community feedback themes
- API (LTXV API) — revenue split (Resellers / Contracts / Self-serve), new endpoints, top gen types, self-serve funnel, PQL/PEL counts, top inbound industries
- Studio Enterprise — active vs total contract orgs, new contracts/pilots, total + LTX-model token consumption with WoW%, share-of-video-tokens, share-of-gens
The post leads with an LLM-generated 2-3 sentence TL;DR that follows strict materiality and "no filler" rules — see n8n/tldr_system_prompt.md.
Architecture
Schedule Trigger (Mon 09:00 UTC)
↓
Run BigQuery ← queries/weekly_report_combined.sql (10 rows: section, data_json)
↓ (10 items)
Parse Sections ← n8n/parse_sections.js (1 item: { sections: {...} })
↓
Render Body ← n8n/render_body.js (1 item: { header, body, ... })
↓
Generate TLDR ← n8n/tldr_system_prompt.md (Anthropic / OpenAI node)
↓
Combine ← n8n/combine.js (1 item: { final_message, ... })
↓
Slack Message (HTTP Request → incoming webhook)
Critical detail: the BigQuery script returns a single result set of 10 rows, each carrying one report block as a JSON-encoded string in data_json. n8n's native BigQuery node (jobs.query) only surfaces the last statement's output, so the original multi-statement script in dwh-data-model-transforms was rewritten into one SELECT ... UNION ALL ... here. KPI logic is unchanged; only the wrapping is different.
Repository layout
ltx-leadership-weekly-report/
├── SKILL.md ← this file
├── queries/
│ └── weekly_report_combined.sql ← single-output SQL for n8n's BQ node
├── n8n/
│ ├── parse_sections.js ← Code node #1 (parse 10 JSON rows → object)
│ ├── render_body.js ← Code node #2 (render Slack body)
│ ├── tldr_system_prompt.md ← System prompt for the LLM node
│ └── combine.js ← Code node #3 (TL;DR + body → Slack post)
└── references/
└── report-template.md ← visual reference for the rendered post
Instructions — first-time setup
1. Create credentials in n8n
- BigQuery service account — JSON key for a service account with
bigquery.jobs.create and read on ltx-dwh-prod-processed.*. Set the credential's default project to ltx-dwh-explore (where the query bills against, no required dataset).
- Anthropic API key — for the TL;DR node.
- Slack incoming webhook — one URL per destination channel. Create the webhook at
api.slack.com/apps → your bot → Incoming Webhooks. The webhook is bound to a specific channel; switching channels means a different webhook URL.
2. Build the workflow
Create the 7 nodes in this exact order, matching the names below (the names matter — combine.js references $('Render Body').first().json by name):
| # | Node name | Type | Configuration |
|---|
| 1 | Schedule Trigger | n8n Schedule trigger | Mondays, 09:00 UTC |
| 2 | Run BigQuery | Google BigQuery → "Execute a SQL query" | Paste queries/weekly_report_combined.sql. Use Standard SQL. |
| 3 | Parse Sections | Code (JavaScript) | Paste n8n/parse_sections.js. |
| 4 | Render Body | Code (JavaScript) | Paste n8n/render_body.js. |
| 5 | Generate TLDR | Anthropic → "Message a model" | Model claude-sonnet-4-5, temperature 0.2, max tokens 300. System message: paste content between the BEGIN/END markers in n8n/tldr_system_prompt.md. User message: ={{ $json.body }}. |
| 6 | Combine | Code (JavaScript) | Paste n8n/combine.js. |
| 7 | Slack Message | HTTP Request | POST to your Slack webhook URL. Body type JSON: { "text": "{{ $json.final_message }}" }. |
3. Test
Execute manually (Monday morning is fine, or any time — the SQL is parameterized off current_date). Inspect each node:
- Run BigQuery: 10 items, each with
{ section, data_json }.
- Parse Sections: 1 item with
sections keyed by A_oss_summary … J_studio_summary.
- Render Body:
header, body, week_start, week_end. Body should look like references/report-template.md.
- Generate TLDR: 2-3 sentences, numbers in
*bold*, no em-dashes, no banned filler.
- Combine:
final_message ready to post.
- Slack Message: posts to the channel.
If you switch LLM provider, the TL;DR field path may change — combine.js already tries the common Anthropic / OpenAI / LangChain shapes, but verify in the run log.
Knobs
| Knob | Where | Current value | Why |
|---|
| Schedule | Schedule Trigger node | Mon 09:00 UTC | Reflects ISO-week ending the previous Sunday |
| Materiality threshold (general) | tldr_system_prompt.md | |WoW%| ≥ 25% | Below this is exec-noise |
| Materiality threshold (totals) | tldr_system_prompt.md | |WoW%| ≥ 15% | Total revenue / total tokens move slowly |
| PEL volatility | tldr_system_prompt.md | Always skip | Marketing PEL swings are noisy |
| Section coverage | tldr_system_prompt.md | TL;DR may omit quiet sections | Don't pad with "OSS was steady" |
| Bold rule (body) | render_body.js | Bold headline numbers only | Not WoW%, not "was X%" context |
| Direction arrow | render_body.js | ↑ ↓ 0% | Visual scanning, no +/- chars |
| Em-dash policy | both | Banned everywhere | Avoids "AI slop" appearance |
Constraints
DO NOT
- Run the original multi-statement
weekly_report_combined.sql from dwh-data-model-transforms through n8n's BQ node — only the last block (J_studio_summary) will come out. Use queries/weekly_report_combined.sql here.
- Rename the n8n nodes "Render Body" or "Generate TLDR" without updating the references in
combine.js.
- Add bolding to WoW percentages, "was X%" context, or non-numeric words. Body must follow the locked layout in
references/report-template.md.
- Introduce em-dashes (
—) or en-dashes (–) anywhere in the body or TL;DR. Use commas / parentheses / colons.
- Trust a single-week PEL move > ±50% — confirm with the body's other numbers before letting the LLM headline it.
- Hardcode the Slack webhook URL inside
combine.js. Pass it via the Slack Message node only.
DO
- Update
references/report-template.md whenever render_body.js layout changes — the template is the visual contract.
- Bump the
Reference TL;DR block in tldr_system_prompt.md after every prompt change so we have a regression anchor.
- Keep
queries/weekly_report_combined.sql in lockstep with dwh-data-model-transforms/queries/weekly_report_combined.sql. KPI changes there must be ported here.
References
- Source SQL (multi-statement, dev/EDA version):
dwh-data-model-transforms/queries/weekly_report_combined.sql
- Spec doc with KPI definitions:
dwh-data-model-transforms/queries/weekly_report_combined.md
- BigQuery cost: ~537 MB scanned per run (dry-run upper bound).