Skip to content

Upgrade to monetizacion.j-lab.tools: real AI chat, deeper analysis, J-Lab design#18

Open
luisassardo wants to merge 2 commits into
mainfrom
jlab-upgrade
Open

Upgrade to monetizacion.j-lab.tools: real AI chat, deeper analysis, J-Lab design#18
luisassardo wants to merge 2 commits into
mainfrom
jlab-upgrade

Conversation

@luisassardo

Copy link
Copy Markdown
Owner

Rebuilds the Meta monetization explorer as a J-Lab tool ahead of the move to monetizacion.j-lab.tools.

What changed

Real AI chat (was fake)

The old "AI" was keyword matching. Now POST /api/ai/chat uses Claude with tool-use over safe predefined query functions (top accounts, by country/year/program/language, search, summary). Claude picks tools and composes a grounded answer in the user's language — no arbitrary code/SQL, no hallucinated numbers.

  • Server-side ANTHROPIC_API_KEY; default model claude-haiku-4-5 (J-Lab standard).
  • Graceful fallback: no key, rate limits, API errors, or loop-cap all degrade to the local keyword engine with HTTP 200 (engine field tells the UI which path answered). /api/query kept unchanged.

Deeper analysis for reporting (/api/analysis/*)

coordinated-bursts (same-day/same-country creation), program-migration (cohort program shift), verified-gap (unverified accounts pulling revenue), country-asymmetry (normalized per-country), growth-outliers (young pages, big audiences). Surfaced as leads, not verdicts.

Data: Latin America + importer

Scope widened from Central America to all Latin America. New scripts/import_archive.py normalizes the archive's raw "Export CSV" (no public API) → the 17-field schema: tolerant of column-casing/UTF-8/escaping quirks, maps messy languages, nulls ghost/epoch dates, filters to LatAm by ISO-2 code, dedupes. --dry-run prints a kept/dropped summary.

Design → J-Lab

Vendored static/css/tokens.css (Inter Tight / Instrument Serif / JetBrains Mono, dark default + light mode). Restyled all three templates; Chart.js recolored from CSS vars; chat panel modeled on the J-Lab Chat component; EN/ES toggle + theme toggle; server-side i18n (Spanish default). Keeps monetization.wtf / WHAT TO FIX / CC BY-ND 4.0 + Vector Crítico attribution.

Config

render.yaml (service monetizacion-jlab, Anthropic env, ANTHROPIC_API_KEY as a dashboard secret), .env.example, requirements.txt (+anthropic), README rewrite.

Verification

  • All page + API + analysis endpoints return 200; AI chat fallback verified end-to-end (no key → engine: local).
  • Importer tested on the existing CSV (3,086 rows pass through) and a synthetic messy export (casing/language/ghost-date/non-LatAm/dedupe handling all correct).
  • Dashboard, account, and widget pages verified in-browser (dark + light, ES + EN), no console errors.

Follow-ups for deploy

  1. Set ANTHROPIC_API_KEY as a Render secret to enable the Claude path (works without it via fallback).
  2. Point monetizacion.j-lab.tools DNS at the service.
  3. Run a fresh LatAm export through scripts/import_archive.py to refresh data/accounts.csv.

🤖 Generated with Claude Code

…sign

- Backend: replace the fake keyword "AI" with a real Claude tool-use chat
  (/api/ai/chat) grounded in the dataset via safe predefined query functions;
  graceful fallback to the local keyword engine when no ANTHROPIC_API_KEY or on
  any error. Refactor process_query() into reusable tool functions + registry.
- Add 5 analysis endpoints for reporting: coordinated-bursts, program-migration,
  verified-gap, country-asymmetry, growth-outliers (leads, not verdicts).
- Importer scripts/import_archive.py: normalize the archive's raw Export CSV to
  the 17-field schema, filter to Latin America by ISO-2 code, clean
  casing/encoding/languages/ghost-dates, dedupe.
- Design: vendor the J-Lab tokens.css and restyle index/account/widget; recolor
  Chart.js from CSS vars; chat panel modeled on the J-Lab Chat component;
  EN/ES toggle + dark/light theme; server-side i18n.
- Branding/domain: J-Lab tool with Vector Critico + WHAT TO FIX / CC BY-ND 4.0
  attribution; update render.yaml (service + Anthropic env), .env.example, README.
- Scope: Latin America (was Central America only).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment thread app.py
lang = resolve_lang()
resp = make_response(render_template(template, lang=lang, t=I18N[lang], **ctx))
if request.args.get('lang') in ('es', 'en'):
resp.set_cookie('lang', lang, max_age=60 * 60 * 24 * 365, samesite='Lax')

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9b0228c57c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app.py
if any(w in q for w in ['top', 'mejores', 'mayores', 'más suscriptores', 'mas suscriptores', 'largest', 'biggest']):
nums = re.findall(r'\d+', q)
n = min(int(nums[0]), 50) if nums else 10
return render_tool_result_md('top_accounts', tool_top_accounts(n), lang)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Pass country filters to the local top tool

When the new /api/ai/chat path falls back to the local engine (no Anthropic key, rate limit, or API error), a country-scoped top query such as the page placeholder “¿Cuáles son las 10 cuentas mayores en Guatemala?” enters this branch but calls tool_top_accounts(n) without the country. With the current CSV, that returns the global top accounts (including El Salvador/Costa Rica rows) instead of Guatemala-only results, so the promised graceful fallback gives incorrect grounded answers whenever AI is unavailable.

Useful? React with 👍 / 👎.

…port

- Reverse-engineered the archive's CSV export endpoint (csv_data_table) and
  refreshed data/accounts.csv to all 22 Latin American countries: 63,846
  Facebook accounts, fresh through 2026-04-25 (was a ~3K Central America
  snapshot through Jan 2026).
- scripts/import_archive.py gains a `--fetch` mode that pulls every LatAm
  country live from that endpoint and normalizes in one command:
    python scripts/import_archive.py --fetch --output data/accounts.csv
  (manual --input export path still supported). Normalizes long ISO country
  names to clean short names.
- Fix: load_data() now fills blank string cells (name/handle/language/location)
  so empty names don't serialize as NaN / invalid JSON in the larger dataset.
- README documents --fetch as the primary refresh path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants