gong-product-intelligence: add Next.js UI + onboarding wizard#56
Open
Yuval Fainberg (YuvalFainberg) wants to merge 6 commits intomainfrom
Open
gong-product-intelligence: add Next.js UI + onboarding wizard#56Yuval Fainberg (YuvalFainberg) wants to merge 6 commits intomainfrom
Yuval Fainberg (YuvalFainberg) wants to merge 6 commits intomainfrom
Conversation
Adds an interactive web UI for the Gong product intelligence agent on top of
the existing Python pipeline. Users can configure runs (product, dates,
audience, focus area, optional org filter for Studio), watch progress live,
view a clustered evidence-anchored report, and chat with grounded citations.
What's new
----------
* `ui/` — Next.js 16 app
- configure / running / report / q&a tabs scoped to a single analysis run
- localStorage-backed multi-run history with per-run chat persistence
- Studio audience picker: non-converted / pilot / contract, with a searchable
org list (or "all pilots / contracts") backed by /api/orgs
- Live BQ count preview while configuring
- SSE-streamed terminal during analysis with Retry on dropped connection
- Drill-down drawer grouped by category (strengths / weaknesses /
feature requests / quotes) with verbatim evidence quotes
- Chat tab grounds Claude in the active run's per-call evidence; answers
cite [[Company]] chips that open the drill panel
- Onboarding wizard auto-opens for new users — checks ANTHROPIC_API_KEY,
gcloud auth, Python deps, etc. and links to Yuval on Slack for the key
scripts/analyze_calls.py — fixes and new flags
----------------------------------------------
* New flags: `--date-to`, `--focus`, `--org`
* `--conversion-status` accepts pilot / contract for studio (in addition to
non-converted / converted / both)
* Studio SQL keeps McCann_NY (pilot) and McCann_Paris (contract) as separate
picker entries while sharing a `mccann` match key — leads/calls data
doesn't distinguish offices
* Per-company lead dedup via ROW_NUMBER (was multiplying matched calls — e.g.
DirecTV with 70+ SF opportunities was being analyzed 70 times)
* Defensive dedup of `to_process` and aggregation `scoped_results` by
conversation_key
* Aggregation now filters to the current run's BQ scope (cross-run cache
was leaking calls from previous runs into the report)
* Summary always regenerated per run (no more stale executive summary)
* Stores `_run_meta` (product, dates, conversion, org, focus,
conversation_keys) in aggregated.json
Other
-----
* `README.md` — setup walkthrough, prerequisites, troubleshooting
* `scripts/requirements.txt` — anthropic, google-cloud-bigquery, slack-sdk
* `.gitignore` — excludes `data/` (verbatim quotes + Slack context never
leave the local machine)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The /api/count and /api/orgs endpoints would silently fail when the user lacked BQ permissions or auth — UI just showed "—" with no hint of why. Now both errors render an inline BQErrorBlock with: - The verbatim error message from BigQuery - Diagnosis (permission issue vs generic) - A `bq query` command the user (or their AI assistant) can run to confirm - Direction to ping Yuval on Slack for IAM access if it's a permission issue Makes it obvious to a fresh user (and to a tool like Cursor reading their screen) what's broken and how to fix it. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The gcloud check used to only verify that ADC credentials existed locally.
That would pass for any Lightricks employee — even those without IAM read
access on ltx-dwh-prod-processed. They'd see ✓ on Google Cloud, then hit
silent BQ failures the moment they touched the configure tab.
Now the check runs `SELECT 1 AS ok` against ltx-dwh-prod-processed via the
BigQuery client. Three outcomes:
- ADC missing → step shows the gcloud login command
- ADC present + BQ access ✓ → step is green, detail says "read access
to ltx-dwh-prod-processed confirmed"
- ADC present + BQ access ✗ → step is red, body explicitly says
"authenticated but no IAM access", and the
note tells the user to ping Yuval on Slack
for ltx-dwh-prod-processed read role
Surfaces the most common new-user blocker before they hit a wall on
configure / running tabs.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Each failing step now exposes a ready-made AI assistant prompt that the user can hand to their local Cursor or Claude Code instance to fix the problem end-to-end (install deps, run gcloud login, draft a Slack DM to Yuval for IAM, etc.). Specifically: - pythonDeps: prompt that runs pip install + verifies imports - gcloud (no ADC): prompt that runs gcloud auth + verifies token - gcloud (no BQ access): prompt that runs the bq SELECT 1 test, then helps the user draft a polite Slack message to Yuval requesting BigQuery Data Viewer + Job User roles on ltx-dwh-prod-processed - anthropic: prompt that walks through pulling the company key from 1Password / Slack and adding it to .env.local without committing UI-wise: each prompt sits in an amber callout under the step's command box, with its own "copy prompt" button. Distinct color from the purple "note" callout so it's clear which is human-readable advice vs. machine-readable instruction. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
A batch of UX/correctness improvements based on running the tool with fresh
users at Lightricks. No changes to the per-call analysis prompts or the
caching contract.
Onboarding & defaults
- App always lands on the configure tab (not the latest report). The latest
run is still active in the sidebar and one click away.
- "LTX · product intel" brand in the appbar is clickable — same as
"+ New analysis", brings you back to a fresh configure screen.
- Removed the unimplemented "Save preset" button.
- Onboarding wizard distinguishes "no ADC credentials" from "authenticated
but no BQ access" by actually running SELECT 1 against
ltx-dwh-prod-processed. The no-bq-access case now points the user toward
a local fix (re-auth, set quota project) instead of asking a teammate for
IAM — that was wrong advice; in practice it's almost always a local
connection problem.
- All references to a specific person renamed to "one of the LTX data team
members" except where the underlying ask is for a shared secret.
Multi-select audience & orgs (studio)
- Audience picker is now multi-select: any combination of non-converted /
pilot / contract. Help text adapts ("combined: pilot + contract").
- Company picker is shown whenever pilot or contract is in the selection
(previously only when one of them was selected alone). Lists orgs from
whichever plan types are active.
- Company picker is now multi-select too — pick zero (= all) or many.
"All" row at the top is a radio-style mutually-exclusive option;
individual companies are checkboxes with a small PILOT/CONTRACT badge.
- Wire format for both is CSV in the existing `conversion` and `org` JSON
fields. Backwards-compatible with single-value runs already in
localStorage.
- /api/count and the studio SQL in analyze_calls.py both build OR predicates
for audiences and IN clauses for multiple orgs. New helper
`build_studio_conversion_filter` consolidates the logic.
- Surfaces inline BQ errors in ConfigureView when /api/count or /api/orgs
fail, with a copyable diagnostic command and pointer to the onboarding
AI-prompt. (Previously failures showed "—" with no hint.)
Org list visual
- Replaced the cramped 3-col chip grid with a single-column scrollable
list. Each row: checkbox + company name + plan-type badge. Much easier to
read with 30+ companies.
RunningView redesign
- Phase stepper (Loading context → Querying BQ → Analyzing → Clustering →
Complete) at the top with a pulsing dot on the active phase.
- Progress card with live counters: progress (X / Y), cached, new, phase.
- "Recently analyzed" feed showing the last 6 calls processed with company,
industry, and a colored sentiment badge.
- Python deprecation warnings (urllib3, google-auth, etc.) are filtered out
of the curated mini-log — they're still available in the collapsible
"Show full terminal log" toggle.
- Errors that are NOT noise get their own red error card.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The BQ clients were pinned to `ltx-dwh-prod-processed` for the project ID, which forced jobs to be CREATED on that project. Most Lightricks accounts have BigQuery Data Viewer on the warehouse but NOT bigquery.jobs.create — so every fresh user hit "Access Denied" on /api/count and /api/orgs the moment they tried to use the tool. Fix: never pin the BQ client. Jobs are now billed to the user's own ADC quota project; data still comes from ltx-dwh-prod-processed via the fully- qualified table names already used everywhere in the SQL. Users just need: - bigquery.jobs.create on any project they belong to (default for all accounts) - bigquery.dataViewer on ltx-dwh-prod-processed (the standard analytics role) Optional `GCLOUD_BILLING_PROJECT` env var lets a user pin billing to a specific project if they want. Other changes: - /api/setup test query now actually queries a prod table (LIMIT 1) instead of a project-less SELECT 1. Validates BOTH jobs.create on user's billing project AND dataViewer on the warehouse — the real combined permission the app needs. - Onboarding wizard's NO_BQ_ACCESS prompt rewritten: tells the user to point set-quota-project at one of THEIR Lightricks projects (not at ltx-dwh-prod-processed, which they don't own). Verification query now uses a real warehouse table. - BQ error block in ConfigureView updated with the same corrected guidance. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a self-hosted Next.js UI for the Gong product intelligence agent. Users configure runs, watch live progress, view clustered evidence-anchored reports, and chat with grounded citations — all on top of the existing Python pipeline.
Also fixes several correctness bugs in
analyze_calls.pythat were silently inflating reports and leaking data across runs (details below).What changed
New UI (
agents/gong-product-intelligence/ui/)non-converted,pilot,contract— with a searchable org list (or "all pilots/contracts")localStoragewith per-run chat persistence[[Company]]chips in answers open the drill panelANTHROPIC_API_KEY, gcloud auth, Python deps; links to Yuval on Slack for the company keyPipeline fixes (
scripts/analyze_calls.py)--date-to,--focus,--orgflags--conversion-statusacceptspilot/contractfor StudioROW_NUMBER(was multiplying matched calls — e.g. DirecTV with 70+ SF opportunities was being analyzed 70x)mccannmatch key — leads/calls data doesn't distinguish offices_run_meta(product, dates, conversion, org, focus, conversation_keys) inaggregated.jsonNew supporting files
README.md— setup, prerequisites, troubleshootingscripts/requirements.txt—anthropic,google-cloud-bigquery,slack-sdk.gitignore— excludesdata/(verbatim quotes + Slack context stay local)Test plan
pip install -r scripts/requirements.txtcd ui && npm install && npm run build— passescp ui/.env.example ui/.env.local+ addANTHROPIC_API_KEYgcloud auth application-default loginnpm run dev→ openlocalhost:3000🤖 Generated with Claude Code