avoma-notes
Explore and integrate Avoma notes data into extraction pipeline and dashboard visualizations.
Why
When extraction began, only raw transcripts were available. Avoma now provides structured notes alongside transcripts — summaries, talking points, action items, and other metadata that can enrich our analysis. This data could improve extraction accuracy, provide additional signals for visualization, and help us understand prospect intent more deeply.
Early Avoma API work (c6.sagetap-integration context) confirmed notes endpoint is accessible. A sample note has been examined but we need a broader sample to understand:
- What information is consistently present across calls?
- Which fields are most useful for segmentation, filtering, or insights?
- Can notes improve extraction quality or provide complementary signals?
Objectives
Phase 1: Data exploration (understand what we have) ✓
- Download 7 sample calls with notes from Avoma API (Brooks, Starbucks, Surepath, Wunderkind, Dropbox, Airbnb, Cam)
- Compare note structure across calls — two distinct templates discovered (sales vs. technical chat)
- Catalog which note fields appear consistently vs. sporadically (see
findings.md) - Document data quality patterns — AI-generated custom sections vary per call; standard sections consistent across sales calls
Phase 2: Analysis (how does it help us?) ✓
- Compared 5 calls side-by-side: Claude extraction vs. Avoma notes (see
comparison.md)- Pain points: strong overlap (3/5 calls). Classification differs — Avoma uses Risk for things Claude calls pain points
- Feature requests: fundamentally different — Avoma conflates features demoed with features requested. Claude is far more useful for roadmap prioritization
- Value signals: Claude significantly better — Avoma misattributes team member quotes as positive moments in 2/5 calls
- New data only in notes: action items (5/5), decision making (3/5), risks/blockers (4/5), current workflow (5/5)
- Identified top 3 fields for integration: actionItems, decisionMaking, risks
- Assessed notes as supplementary context — should feed into Claude prompt as appendix, not replace extraction
Key finding: The two systems are complementary, not redundant. Claude wins on insight quality (verbatim quotes, speaker attribution, interest scoring). Avoma wins on deal mechanics (action items, decision authority, deployment risks).
Phase 3: Integration planning (scope for future cycles) ✓
- Designed integration plan with 3 additions + 1 enhancement (see
integration-plan.md)actionItems— parsed from Avoma notes at index time (no re-extraction)decisionMaking— added to Claude extraction prompt (requires re-extraction)risks— added to Claude extraction prompt (requires re-extraction)- Feed Avoma notes as supplementary context in extraction prompt
- Identified implementation order: notes fetching → action items → prompt changes → batch re-extract
- Identified dashboard opportunities: action items view, decision maker map, risk heatmap, deal readiness score
Scope
Key files:
- Pipeline:
pipeline/extract.ts,pipeline/batch.ts,pipeline/prompts/extract-call.md - Schema:
schemas/call.ts(may need new optional fields) - Data:
data/raw/(sidecar metadata), Avoma API integration in.claude/memory/avoma-api.md - Site:
site/pages/calls.vue, component display logic - Sample note:
cycles/c7.avoma-notes/sample-note.md(reference)
Not in scope yet:
- Full re-extraction with notes integrated (defer to Phase 3 → future cycle)
- Dashboard UI redesign (explore only in Phase 2)
Key Changes
- Downloaded 7 sample notes from Avoma API →
cycles/c7.avoma-notes/samples/(md + raw JSON) - Created
cycles/c7.avoma-notes/findings.md— note structure, section consistency matrix, data quality observations - Created
cycles/c7.avoma-notes/comparison.md— 5-call side-by-side comparison with quality scoring - Built
cycles/c7.avoma-notes/fetch-sample-notes.ts— reusable script for fetching/formatting Avoma notes - Created
cycles/c7.avoma-notes/integration-plan.md— 3 schema additions + 1 prompt enhancement, ordered by dependency
Outcome
Avoma notes are a complementary data source to our Claude extraction — not redundant, not a replacement. Claude wins on insight quality (verbatim quotes, speaker attribution, interest scoring). Avoma wins on deal mechanics (action items, decision authority, deployment risks).
All 24 synced calls now have notes sidecars at data/raw/{uuid}.notes.json. Future npm run fetch calls save notes automatically.
Implementation Plan
Step 1: Schema additions (schemas/call.ts)
Add three new optional fields to CallData:
// After positioning field:
actionItems?: ActionItem[]
decisionMaking?: DecisionMaking
risks?: Risk[]
New interfaces:
interface ActionItem {
text: string // what needs to be done
owner: string // who is responsible
timestamp?: string // mm:ss into call
source: 'avoma' // always from Avoma notes
}
interface DecisionMaking {
decisionMaker?: string
authority?: string // description of authority level
process?: string // committee, sole authority, etc.
approvers?: string[]
verbatim?: string
speaker?: string
confidence: 'high' | 'medium' | 'low'
}
interface Risk {
text: string
verbatim?: string
speaker?: string
category: RiskCategory
confidence: 'high' | 'medium' | 'low'
}
type RiskCategory =
| 'technical-compatibility' // conflicts with existing tools (CrowdStrike, eBPF)
| 'deployment-blocker' // missing prerequisites (object store, namespace)
| 'organizational' // approval needed, wrong team, politics
| 'security-privacy' // data sensitivity, privacy policy conflicts
| 'resource-constraints' // team bandwidth, competing priorities
Also add actionItems, risks, and decisionMaking summary fields to CallIndexEntry for list views.
Step 2: Extraction prompt updates (pipeline/prompts/extract-call.md)
Add decisionMaking to output schema (after positioning):
"decisionMaking": {
"decisionMaker": "<name of person with authority to approve, or null>",
"authority": "<description: 'unilateral', 'needs VP approval', 'committee', etc.>",
"process": "<how decisions are made if discussed>",
"approvers": ["<other people who need to sign off>"],
"verbatim": "<exact quote revealing decision dynamics>",
"speaker": "<name>",
"confidence": "<high|medium|low>"
}
Add risks to output schema (after decisionMaking):
"risks": [
{
"text": "<description of deployment risk or blocker>",
"verbatim": "<exact quote if available>",
"speaker": "<name>",
"category": "<technical-compatibility|deployment-blocker|organizational|security-privacy|resource-constraints>",
"confidence": "<high|medium|low>"
}
]
Add guideline 15 distinguishing risks from objections:
Risks vs. objections: An objection is pushback ("I don't think this will work"). A risk is a factual obstacle ("our CrowdStrike agent also uses eBPF"). Risks are deployment blockers that need mitigation, not persuasion. Include risks from both prospect and Qpoint speakers — risks are factual, not opinion.
Add guideline 16 for decision-making:
Decision making: Look for who has budget authority, who can approve a POC, and what the procurement process looks like. Only extract what is explicitly stated — do not infer decision authority from job titles alone.
Add Risk Categories section at the end alongside existing category lists.
Step 3: Feed Avoma notes as supplementary context (pipeline/extract.ts)
In extractCall(), after the metadata sidecar injection (line ~159), add notes sidecar injection:
- Check for
data/raw/{callId}.notes.json - If found, parse blocks into readable markdown (extract a
notesToMarkdown()helper fromfetch-sample-notes.ts) - Inject before
## Transcript:
Avoma AI Notes (supplementary context)
The following AI-generated notes were produced by Avoma's meeting intelligence system. Use these as supplementary context — they may surface details the transcript alone misses. Do NOT treat these as ground truth. If notes conflict with the transcript, trust the transcript. Avoma sometimes misattributes speakers or conflates features demoed with features requested.
{notes markdown}
Also add matching injection logic to `pipeline/batch.ts`.
### Step 4: Parse action items from notes (`pipeline/build-index.ts`)
At index build time, for each call:
1. Check for `data/raw/{callId}.notes.json`
2. Find `highlight_category_action_item` section
3. Parse list items into `ActionItem[]` (owner from sub-list grouping, text from content, timestamp from transcript blocks)
4. Inject into processed JSON as `actionItems` field
This runs without re-extraction — it enriches existing processed data with notes-derived action items.
### Step 5: Batch re-extraction
After steps 1-3 are complete:
1. Run `npm run extract:batch -- --force` to re-extract all calls with the expanded prompt + notes context
2. Then run step 4 to layer action items on top
3. Run `npm run index` to rebuild the aggregated index
**Estimated cost:** ~$0.90 for 24 calls ($0.037/call baseline, slightly more input tokens from notes).
### Step 6: Validation
- [ ] Spot-check 3-5 re-extracted calls for `decisionMaking` and `risks` quality
- [ ] Verify `actionItems` parsed correctly across all calls
- [ ] Check `max_tokens: 4096` is still sufficient with new fields (monitor for truncation)
- [ ] Run `npm run index` and verify new fields appear in `all-calls.json`
---
### Implementation order and dependencies
Step 1 (schema) ──→ Step 2 (prompt) ──→ Step 5 (re-extract) ↓ Step 3 (notes context in extract.ts) ────→ Step 5 ↓ Step 4 (action items parser) ─────────→ runs after Step 5 ↓ Step 6 (validation)
Steps 1-3 are code changes (no API cost). Step 5 is the single batch re-extraction. Step 4 layers on action items post-extraction. Step 6 validates everything.
Artifacts
- PICKUP.md — parked-state re-entry note
- PICKUP.md
- comparison.md
- findings.md
- sample-note.md