Update from Sync Service
This commit is contained in:
291
Prompts/Speaker Auto-Tag Prompt.md
Executable file
291
Prompts/Speaker Auto-Tag Prompt.md
Executable file
@@ -0,0 +1,291 @@
|
||||
|
||||
|
||||
Performance-optimized version of Speaker Auto-Tag Prompt with batched People note resolution and context-based confidence refinement.
|
||||
|
||||
Self-contained prompt for tagging unidentified speakers in one transcript stub using vault data (People notes, calendar attendees). Returns proposed speaker mappings; the caller handles review and writes.
|
||||
|
||||
**CRITICAL:** Never read the full transcript in a single Read call. Transcripts exceed the 10k token file-read limit. Use chunked reads (limit=500 per chunk). See Step 2.
|
||||
|
||||
**OPTIMIZATION FOCUS:** Read People notes deterministically from the parent meeting invitees list (no broad name-based glob), batch all invitee reads in parallel, build a comprehensive context table before analysis, and use role/context matching for confidence refinement.
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Setup
|
||||
|
||||
If Read, Glob, Grep, and Bash are not already available, load them: ToolSearch("select:Read,Glob,Grep,Bash")
|
||||
|
||||
Extract from the calling message:
|
||||
- Transcript — path to the transcript stub file
|
||||
- Microphone user — full name of the person at the microphone
|
||||
- Calendar Attendees — pre-fetched attendee context (optional; skips Step 4 if provided)
|
||||
- People Roster — pre-built People context table (optional; skips Step 3 if provided — use as the People context table directly)
|
||||
- People Folder — folder name for People notes (default: People)
|
||||
- Output format — expected output format for the mapping
|
||||
|
||||
Path resolution: try the Transcript path as-is. If not found, error with the path.
|
||||
|
||||
Vault root derivation: extract vault root from the transcript path by removing the transcript folder suffix. Use this root combined with People Folder for all lookups.
|
||||
|
||||
Derived values (from filename, no read needed):
|
||||
- MEETING_TITLE — strip date prefix (first 13 chars for "YYYY-MM-DD - " or first 11 chars for "YYYY-MM-DD ") and " - Transcript" suffix
|
||||
- SANITIZED_SUBJECT — take MEETING_TITLE, replace /, \, : with hyphens. Used for cache Glob in Step 2.
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Read Transcript + Glob Roster Cache + Glob People Notes
|
||||
|
||||
**Round 1 — issue in a single parallel batch:**
|
||||
- Read(transcript_path, limit=60) — frontmatter only
|
||||
- Bash: wc -l transcript_path — total line count
|
||||
- Glob("Caches/Speaker Rosters/SANITIZED_SUBJECT.md") — roster cache for Step 5
|
||||
|
||||
Extract from frontmatter:
|
||||
- session_id (or macwhisper_session_id for WhisperCal stubs)
|
||||
- speakers — array with name, id, stub flag, line_count per speaker
|
||||
- meeting_note — wiki-link to parent meeting note (used in Step 3a)
|
||||
- calendar_event — event title, "none", or absent
|
||||
- calendar_attendees — array of plain string names (or invitees for WhisperCal, or meeting_invitees for wiki-link format like "- [[Name]]")
|
||||
- meeting_subject — used to validate cache match
|
||||
- is_recurring — enables roster cache path
|
||||
- pipeline_state — current pipeline state
|
||||
- tags — detect WhisperCal stubs (tags: [transcript])
|
||||
|
||||
Pipeline state: any value (tagged, extracted, summarized, titled) or absent means proceed.
|
||||
|
||||
**Round 2 — transcript body chunks in a single parallel batch.** Use the line count from Round 1. Read in chunks of 500 lines, starting after the frontmatter:
|
||||
- Read(transcript_path, offset=61, limit=500) — chunk 1
|
||||
- Read(transcript_path, offset=561, limit=500) — chunk 2
|
||||
- Read(transcript_path, offset=1061, limit=500) — chunk 3 if needed
|
||||
- Continue until total lines are covered.
|
||||
|
||||
Most transcripts need 1 to 3 chunks. The full body across all chunks is the primary input for Step 6.
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Read Invitees from Parent Meeting Note (OPTIMIZED)
|
||||
|
||||
**Skip this entire step if** `People Roster` was provided in the invocation parameters. Use the provided roster as the People context table directly and proceed to Step 4.
|
||||
|
||||
**CRITICAL:** If not skipped, do NOT skip this step. Complete it before Step 4 to maximize cache hits and build context early.
|
||||
|
||||
### 3a. Read Parent Meeting Note
|
||||
|
||||
The transcript frontmatter contains `meeting_note` field with a wiki-link to the parent meeting note (e.g., `[[2026-04-04 - Test Transcript]]`).
|
||||
|
||||
- Extract the meeting note path from the wiki-link
|
||||
- Read the meeting note (limit=100 to capture frontmatter + invitees section)
|
||||
- Extract the `meeting_invitees` field — this contains an array of People note wiki-links or plain attendee names
|
||||
|
||||
Example invitees field:
|
||||
```
|
||||
meeting_invitees:
|
||||
- "[[People/Joe Jackson]]"
|
||||
- "[[People/Tanner Bragg]]"
|
||||
- "[[People/Gregory Porter]]"
|
||||
- "[[People/Andrew Davis]]"
|
||||
```
|
||||
|
||||
Or plain names:
|
||||
```
|
||||
meeting_invitees:
|
||||
- Joe Jackson
|
||||
- Tanner Bragg
|
||||
- Gregory Porter
|
||||
```
|
||||
|
||||
### 3b. Parse Invitees & Build File Paths (DETERMINISTIC)
|
||||
|
||||
For each invitee:
|
||||
- If wiki-link format `[[People/Name]]`: extract the path as `People/Name.md`
|
||||
- If plain name: construct path as `People/{name}.md`
|
||||
|
||||
Issue **ALL** Read calls in a single parallel batch. This is deterministic — no glob phase.
|
||||
|
||||
Example (if 4 invitees):
|
||||
```
|
||||
Read(People/Joe Jackson.md, limit=60)
|
||||
Read(People/Tanner Bragg.md, limit=60)
|
||||
Read(People/Gregory Porter.md, limit=60)
|
||||
Read(People/Andrew Davis.md, limit=60)
|
||||
```
|
||||
|
||||
### 3c. Build People Context Table (Phase 2)
|
||||
|
||||
From each People note read in Phase 3b, extract:
|
||||
- full_name
|
||||
- nickname (if present)
|
||||
- role_title
|
||||
- company/org
|
||||
|
||||
Build a Context value per person as:
|
||||
- `"role_title, company/org"` (both present)
|
||||
- `"role_title"` (org empty)
|
||||
- `"company/org"` (role empty)
|
||||
- `""` (both empty)
|
||||
|
||||
Build a People context table with these fields per person:
|
||||
| Full Name | Nickname | Role/Context | People Note Filename | Source |
|
||||
|
||||
Source values: "meeting_invitee", "calendar", "microphone_user", "vocative_recovery"
|
||||
|
||||
**This table is the foundation for Step 6 confidence refinement. Do not skip to Step 4 until this is complete.**
|
||||
|
||||
### 3d. Roster Cache Merge (If Cache Hit)
|
||||
|
||||
If a cache was found in Step 2:
|
||||
- Compare table from Phase 3c against cached roster
|
||||
- If all invitees are present in cache: use cached full context
|
||||
- If new names found: merge Phase 3c results into cache, update cache generated date
|
||||
|
||||
---
|
||||
|
||||
## Step 4: Calendar Attendees
|
||||
|
||||
Skip if Calendar Attendees was provided in invocation (use it directly). Also skip if People Roster was provided.
|
||||
|
||||
- calendar_event is "none" — skip calendar lookups entirely (ad-hoc meeting)
|
||||
- calendar_attendees, invitees, or meeting_invitees populated — use directly (strip [[ ]] wrappers if present)
|
||||
- No calendar data — proceed without. Calendar context improves confidence but is not required.
|
||||
|
||||
Add all calendar attendees to the People context table from Step 3c with Source="calendar".
|
||||
|
||||
---
|
||||
|
||||
## Step 5: Vocative-to-Speaker Mapping
|
||||
|
||||
### 5a. Vocative Scanning (Pre-Step 6)
|
||||
|
||||
Scan the full transcript body (from Step 2) for direct address patterns:
|
||||
- "[Name], go ahead"
|
||||
- "Thanks, [Name]"
|
||||
- "[Name], what do you think?"
|
||||
- "[Name], can you..."
|
||||
- "Over to you, [Name]"
|
||||
- "[Name]?" (standalone calling)
|
||||
|
||||
### 5b. Match Against People Context
|
||||
|
||||
For each vocative detected, check the People context table (Step 3c):
|
||||
- Match against Full Name (exact or first word)
|
||||
- Match against Nickname
|
||||
- Multiple detections for the same name strengthen signal
|
||||
|
||||
### 5c. Unmatched Vocative Recovery Batch (OPTIMIZED)
|
||||
|
||||
If any vocative names do not match People context:
|
||||
|
||||
Collect all unmatched names (e.g., "Kev", "Chew", "Alex", "Joe").
|
||||
|
||||
Issue recovery Globs in a single parallel batch:
|
||||
```
|
||||
Glob(People Folder/*Kev*.md)
|
||||
Glob(People Folder/*Chew*.md)
|
||||
Glob(People Folder/*Alex*.md)
|
||||
Glob(People Folder/*Joe*.md)
|
||||
```
|
||||
|
||||
For each glob hit:
|
||||
- Issue a Read in a single parallel batch (Phase 2 repeat)
|
||||
- Extract full_name, nickname, role_title, company/org
|
||||
- Add to People context table with Source="vocative_recovery"
|
||||
|
||||
For misses: flag the unmatched_vocative in the final evidence field for that speaker.
|
||||
|
||||
---
|
||||
|
||||
## Step 6: Speaker Identification Analysis
|
||||
|
||||
Analyze the full transcript body (from Step 2), speaker stubs (frontmatter), and **complete** People context table (from Step 3c + 5c) using the rules below. Higher-priority rules override lower ones.
|
||||
|
||||
**CRITICAL — duplicate assignments are expected and correct.** Transcription engines frequently split one real person across multiple speaker tags (e.g., Speaker 1 and Speaker 3 are both the same person). Propose the best match for each tag independently. Do NOT enforce a one-to-one constraint between people and tags. If the evidence says Speaker 1 is "Jane Doe" and Speaker 3 is also "Jane Doe", propose "Jane Doe" for both.
|
||||
|
||||
### Rule 1: Microphone Speaker — CERTAIN
|
||||
|
||||
Assign the Microphone user to the "Microphone" label. If no "Microphone" label exists, assign to the speaker with the most lines. Evidence: "microphone". Never overridden.
|
||||
|
||||
### Rule 2: Calendar Attendees — CERTAIN or HIGH
|
||||
|
||||
- Calendar + vocative match (see Rule 3) = CERTAIN
|
||||
- Calendar + one other transcript signal (style, topic expertise, vocative response) = HIGH
|
||||
- Calendar alone with no transcript evidence = do not assign. Invitees may be absent.
|
||||
|
||||
### Rule 3: Vocative Scanning & Matching
|
||||
|
||||
Vocatives matched in Step 5 now resolve to full names via the People context table.
|
||||
|
||||
- Vocative directly matches a single People note = CERTAIN or HIGH
|
||||
- Multiple independent vocatives resolve to same person = CERTAIN
|
||||
- Unmatched vocative (recovery failed) = flag but do not assign
|
||||
|
||||
### Rule 4: Vocative-to-Response Mapping
|
||||
|
||||
The speaker who talks immediately after being called by name is likely that person. If Speaker A says "Tom, go ahead" and Speaker 3 speaks next, Speaker 3 is likely Tom.
|
||||
|
||||
- Multiple vocative-responses for the same mapping = CERTAIN
|
||||
- Single vocative-response = HIGH
|
||||
- Conflicting mappings = LOW
|
||||
|
||||
### Rule 5: First Name to Full Name Resolution + Context Matching (OPTIMIZED)
|
||||
|
||||
Resolve first names to full names:
|
||||
|
||||
1. Check calendar attendees — if exactly one has that first name, use them.
|
||||
2. Check People context Full Name and Nickname columns.
|
||||
|
||||
**First-name collision (multiple candidates share first name): try disambiguation in order:**
|
||||
|
||||
1. **Context match** (NEW) — if transcript topic/discussion matches one candidate's Role/Context value, resolve at HIGH confidence with evidence "role/context match: [Context]"
|
||||
- Example: Speaker discusses "VMware patching" and context table has "Gregory Kanis - VMware Administrator, Platform Team" → HIGH match
|
||||
- Example: Speaker discusses "observability deployment" and context table has "Tanner Bragg - SRE, Platform Team" and "Tanner Smith - Finance" → HIGH match to Bragg
|
||||
|
||||
2. Calendar preference — if exactly one candidate is a calendar attendee, use them.
|
||||
3. Neither resolves — flag as LOW with all candidates and their Context values listed.
|
||||
|
||||
### Rule 6: Alias / Transcription Error Handling
|
||||
|
||||
For unresolved stubs, check Nicknames for phonetically similar matches to words spoken near that speaker. Confidence: LOW unless corroborated by Role/Context.
|
||||
|
||||
### Confidence Levels (REFINED)
|
||||
|
||||
- **CERTAIN:** microphone user, calendar + vocative, multiple vocative-responses, or multiple independent signals agreeing
|
||||
- **HIGH:** calendar + single signal, single vocative-response, vocative + context match, or calendar + role/context alignment
|
||||
- **LOW:** single weak signal, phonetic guess, ambiguous match, or unresolved collision
|
||||
- **null:** no evidence found
|
||||
|
||||
### Build Proposed Mapping
|
||||
|
||||
For each speaker, record:
|
||||
- index — 0 for Microphone, N for Speaker N
|
||||
- original_name — stub label from transcript
|
||||
- proposed_name — resolved full name, or null (the same person may appear for multiple tags — this is correct)
|
||||
- confidence — CERTAIN, HIGH, LOW, or null if unresolved
|
||||
- evidence — brief signal description (include "role/context match: [matching field]" if used)
|
||||
|
||||
Do not downgrade confidence or skip a match because the same person was already proposed for a different tag. Evaluate each tag on its own evidence.
|
||||
|
||||
---
|
||||
|
||||
## Step 7: Return Results
|
||||
|
||||
Return the mapping in the output format specified by the caller. Do not write changes to the transcript.
|
||||
|
||||
---
|
||||
|
||||
## Caching & Performance Notes
|
||||
|
||||
**Roster Cache Strategy:**
|
||||
- Cache is eligible if meeting_subject exists AND is_recurring is true
|
||||
- Cached People context remains valid for 14 days
|
||||
- On cache hit: skip Step 3 Phase 2 reads entirely (major time savings)
|
||||
- On cache miss or new names: merge results into cache for future runs
|
||||
|
||||
**Tool Call Batching Summary:**
|
||||
- Step 2: 3 parallel calls (Read transcript frontmatter, wc, Glob roster cache) + transcript body chunks in parallel
|
||||
- Step 3: Read parent meeting note → Parse invitees → Read all invitee People notes in parallel (deterministic, no glob)
|
||||
- Step 5c: Recovery Glob batch (vocative recovery only) → Wait → Recovery Read batch (if needed)
|
||||
- Total batches: ~4-5 (vs ~10+ in non-optimized version; eliminates broad name-based glob phase)
|
||||
|
||||
**Expected Impact:**
|
||||
- With fresh People context build: 1-2 minute baseline
|
||||
- With roster cache hit: 30-40% faster (skips Phase 2 reads)
|
||||
- With context matching: 15-20% fewer unresolved speakers vs. non-optimized
|
||||
Reference in New Issue
Block a user