One pipeline: transcribe β anonymize β analyze β aggregate β generate the playbook β test & approve.
What this does. Turns raw call recordings (audio pulled from Google Drive) into text transcripts with OpenAI Whisper. This is the first stage β every stage after it runs on this output.
transcripts/ folder.Each call keeps exactly one transcript β re-running a done file overwrites it in place (no duplicate copies).
No pending files. Load from Drive or upload audio.
Nothing transcribed yet.
model Β· s
Log output appears here during transcriptionβ¦
What this does. Strips personally-identifiable information β names, phone numbers, emails, card numbers β from every transcript, so no customer data ever reaches the LLM. Required before Analyze.
anonymized/. Open one and confirm you see [NAME] / [PHONE] tokens.Reads transcripts/ (Transcribe β Anonymize) and writes redacted copies into anonymized/. Override the source folder below if needed.
One anonymized JSON per call β re-running a done file overwrites it in place (no duplicate copies).
No pending files. Click Load Files.
Nothing anonymized yet.
Redactions:
Log output appears here during anonymizationβ¦
What this does. Runs an LLM over each anonymized call to pull out structured insights β outcome, objections, effective phrases, failure points, QuickBooks errors, and a summary. Writes one analysis JSON per call.
analyses/; use the Review tab here to read individual ones.Extract these fields:
One analysis JSON per call β re-running a done file overwrites it in place (no duplicate copies).
No pending files. Run Anonymize first, then Load.
Nothing analyzed yet.
Log output appears here during analysisβ¦
What this does. Rolls every per-call analysis up into one cross-call picture β the most common objections, recurring QuickBooks errors, and the pitch beats and phrases that consistently work.
Re-running carries the previous aggregate's findings forward (objections / phrases / failure points accumulate, prior entries win) and backs up the old aggregate.json first.
Rolls every per-call analysis into one corpus-wide aggregate: deterministic stats + a single LLM synthesis of objections β rebuttals, winning phrases, and failure points. Feeds the playbook generation (M4-T9).
One LLM synthesis pass over the whole corpus β this is a single call (~30β90s), so there's no per-file progress to show.
An aggregate.json already exists β running again will ask before overwriting it.
Outcomes
Sentiments
Pitch beats
Top QB errors
Rebuttal:
No objections synthesized.
No aggregate yet. Run the Analyze stage on some calls, then Run Aggregation.
Log output appears here during aggregationβ¦
What this does. Converts the aggregate into the production playbook β a master system prompt, a rebuttal library, and flow rules β the assets that replace the hand-written agent config.
aggregate.json (run Aggregate first if it's missing).generated/assets.json β then go to Review.Re-generating merges with the previous assets β your hand-edited rebuttals from Review are preserved (prior entries win; only genuinely-new ones are appended) and the old file is backed up first.
Generate these assets:
Turns the cross-call aggregate into the production assets β master system prompt, rebuttal library, flow rules β that replace the hand-written system.yaml. Test them in the Review stage.
One LLM pass over the aggregate β a single call (~30β90s), so there's no per-item progress to show.
An assets.json already exists β generating again will ask before overwriting it. The previous version is backed up automatically.
No assets yet. Run the Aggregate stage, then Generate.
Log output appears here during generationβ¦
What this does. Reads the anonymized call transcripts, pulls out every question the customer asked, clusters them, and checks whether the agent's playbook can actually answer each one β flagging the gaps (high-frequency questions we can't answer).
coverage_report.md + coverage.json to the coverage volume.Three LLM passes over the corpus: extract customer questions per call β cluster into canonical questions with counts β classify each against the live playbook (covered / partial / gap).
Extracting per call (cached) β for a full 400+ corpus the first run takes a while; you can Stop and resume.
Log output appears here during the runβ¦
Click a row to view that run's questions; β¬ to download its report.
| when | calls | questions | gaps | partial | covered | |
|---|---|---|---|---|---|---|
| LATEST |
| # | question | category | suggestion |
|---|---|---|---|
| No questions in this bucket. | |||
β οΈ Place Call isn't connected to the dialer yet. Set QB_API_BASE_URL on the qb-transcriber app to the qb-api URL (e.g. https://qb-api.147-93-0-99.nip.io, no trailing slash) and redeploy. Then this button dials through qb-api.
Dials a real outbound call on the live agent (current published version) so you can hear it, then come back and give feedback. Uses an auto-picked AI line.
The agent may cite the ticket # to verify the call is legitimate (it never invents one). Agent name overrides the spoken name for this call.
What the agent says to the customer when you advance each step of the LMI remote-session handshake (after the PIN). Leave a field blank to use the built-in wording. Saves live β used on the next call.
Step 4 (βSession liveβ) says nothing β clicking it just confirms the remote session connected and unlocks Pro Advisor transfer.
Just describe what went wrong on a call β like you'd tell a colleague. The Brain figures out which part of the script to change, shows you the exact edit, and applies it on your OK. Live on the next call, no engineer, no redeploy.
This is a mechanical/audio behavior (barge-in, echo, latency, tool gates, voicemail) β it lives in code, not the script, so it can't be changed here. Flag it to the engineer.
Try rephrasing with a concrete before/after, or paste the transcript.
New playbookUpdating playbook Β· β
Probe the agent: type customer lines and see how it replies. Use π Feedback to turn a bad reply into a concrete Call Sections edit.
Type customer lines; the LLM responds as Sarah using the real agent prompt. Keep going to replay a multi-turn call (e.g. reproduce a bad one).
Latest reply:
Not what you wanted? Describe the fix in π Feedback and apply it to the relevant Call Section.
Write the answer in rough form β the Brain rewrites it into polished, conversational phrasing. Approve as-is, tweak, ask for another pass, or add to the library.
Polished reply (edit if you like):
One vetted script per issue type. The agent loads the one matching a call's issue (and can switch mid-call). Goes live on the next call β no deploy.
At call start the agent loads the Core (Section 1), the always-on Behavior Rules (10) and the early phases (Opening, Reaching the owner, Trust). The later walkthrough phases load on demand as the call reaches them. Each section has an Instruction, optional FAQ blocks, and an optional Steps block β all saved together when you press Save, live on the next call.
Shortcodes you can use in any section (filled per call from the form/CSV, else the default in the Variables / Shortcodes section): {agent} Β· {customer} Β· {company} Β· {issue} Β· {ticket}.
Section 1 is the always-on Core (loaded on every call). Use {agent} where the agent's name should go.
This is the exact first line the customer hears β spoken word-for-word. Keep it to one natural sentence; use {agent} for the agent's name.
Always-on Behavior Rules β injected on every call and win over the script on conflict. Not a phase (never in the call's step order). Use {agent} for the name.
Not spoken β this defines the {shortcode} defaults. One name = default value per line (e.g. agent = Peter); # lines are ignored. The per-call form/CSV value wins; the default here is used when a call doesn't supply one. β οΈ Keep ticket generic text β never a fake case number.
No FAQs yet. Add common questions for this phase β each is its own block.
No steps yet. Add the ordered steps for this use case.
A deny-list of phrases the agent must never say (e.g. claiming to work for Intuit, promising a guaranteed refund). Matched on each spoken sentence β on a hit the agent speaks the replacement instead, or the whole sentence is dropped if you leave the replacement blank. Edits are live on the next call (within ~30s). Matching is case-insensitive.
Guardrails ship in observe-mode by default (CC_GUARDRAIL_FLAG_ONLY=true) β hits are logged to the call Inspector but the audio is not altered. An engineer flips CC_GUARDRAIL_FLAG_ONLY=false on qb-api to start enforcing.
| Phrase | Replacement | Active | |
|---|---|---|---|
of the selected already have output in the volume. Overwrite them, or skip and process only the new ones?
already exists in the volume. Overwrite it?