Churn Call Analysis
STEP 0 — Discover the account and ask the user
Call allo_get_me to confirm the connected Allo account and available scopes.
Then call allo_list_users and allo_list_numbers in parallel to enumerate who and what is available.

Present the user with a scoping question before doing anything else:
"I found [N] users and [N] phone lines on [TEAM NAME].
Who or what should I include in this churn analysis?

Options:
  A) Specific user(s) — list names and let them pick
  B) Specific phone line(s) — list numbers/labels and let them pick
  C) The whole team (all users, all lines)

Also: what date range? (default: last 30 days)"
Wait for the user's answer before proceeding. Do not assume a default scope.
Log this as Step 0 in the run log.

STEP 1 — Retrieve calls for the selected scope
Using allo_search_conversation_items, pull all answered calls within the chosen date range. Apply only the filters the user confirmed:
  - If a specific user was chosen: add user_id
  - If a specific line was chosen: add allo_number
  - If whole team: omit both (searches across all lines)
  - Always set: type=CALL, result=ANSWERED, size=100, sort=DATE
Paginate if has_more=true. Collect all pages before moving on.
Log each API call with method, inputs, and result count.

STEP 2 — First-pass churn detection from summaries
Do NOT fetch transcripts yet.

Each call returned by Step 1 includes a summary field. Read every summary and flag a call as a churn candidate if any of the following signals are present:

Explicit signals: cancel / unsubscribe / closing the account / refund / switching away / leaving / no longer using / not renewing

Implicit signals: unhappy with pricing / not getting value / going with a competitor / service not working as expected / billing dispute / product limitation blocking use / frustrated with a feature gap / trial ending without converting

Note: a call where any rep proactively tries to save a customer — even if the customer hasn't said "cancel" yet — also qualifies.

Mark each call: CHURN_CANDIDATE (yes/no) with a 1-line reason drawn from the summary. Calls with no summary should be deferred to Step 3 for manual review if they are ≥ 2 minutes long.

Exclude calls shorter than 120 seconds at this stage. Log how many were excluded and how many candidates remain.

STEP 3 — Pull full transcripts for churn candidates
Fetch transcripts only for churn candidates using allo_batch_get_conversation_items with extend=transcript. Batch in groups of 6 to avoid token overload — do not exceed 6 per batch call.

For each transcript, confirm whether it is truly churn-related. If a candidate turns out to be unrelated (false positive from summary), discard it and note it in the run log.

For each confirmed churn call, tag every relevant statement:
  CHURN_REASON   — explicit or implied reason the customer is leaving or at risk
  SAVE_ATTEMPT   — what the rep said or offered to retain the customer
  SAVE_OUTCOME   — saved / lost / pending / unclear
  WIN_BACK       — any signal the customer could be re-engaged later
  ROOT_CAUSE     — one of: product gap / pricing / competitor / support failure / onboarding failure / technical issue / billing problem / other

Preserve exact quotes, the speaker's name or role, the context that prompted the statement, and a call reference (ID, date, contact name or number).

STEP 4 — Cluster, rank, and report
Group similar statements into themes. Count how many distinct calls each theme appeared in (occurrence count). Then produce this report:

📊 Churn Call Analysis — [TEAM NAME] — [DATE RANGE]
Scope: [Users / Lines / Whole team — as selected by user]
Calls retrieved: [N total] → [N after length filter] → [N confirmed churn calls]
False positives discarded: [N] (summaries flagged but transcripts didn't confirm)

🔴 Top 10 Churn Reasons
For each reason:
  Short label (e.g., "SMS verification delay outlasted the trial window")
  2–3 sentence summary of how this reason surfaced across calls
  Exact quotes with speaker, context, and call reference
  Root cause category
  Occurrence count

🟡 Top 5 Save Attempts — What Was Tried
For each attempt:
  Short label (e.g., "Trial extension offered to bridge approval wait")
  2–3 sentence summary of the tactic and how the customer responded
  Exact quotes showing the offer and the customer's reaction
  Outcome: Saved / Lost / Pending / Unclear
  Occurrence count

💚 Top 5 Win-Back Signals
For each signal:
  Short label (e.g., "Would return if desk phone support is added")
  2–3 sentence summary of what the customer said that left the door open
  Exact quotes with speaker and call reference
  Suggested follow-up action
  Occurrence count

🏴 Competitor Mentions
List every competitor named across all confirmed churn calls:
  Competitor | # of calls | Context (switching to / coming from / comparing against)

🔧 Run Log
| Method | Key Inputs | Result |
|--------|-----------|--------|
| …      | …         | …      |

Rules that always apply:
  - Never fabricate quotes. If something is inferred, mark it ⚠️ inferred.
  - Occurrence count = distinct calls, not total mentions within one call.
  - If a theme appears in only 1 call, flag it ⚠️ weak signal.
  - If fewer than 3 confirmed churn calls exist, report what's available, flag ⚠️ thin data, and offer to widen the date range before concluding.
  - If allo_get_me or allo_list_users fail, ask the user to provide the team name, user list, or phone lines manually before proceeding.
  - If Allo MCP is unavailable, ask the user to paste transcripts directly.