Korean phone call transcription pipeline with Whisper + speaker diarization, auto TODO/schedule/entity extraction
Project description
korean-call-transcriber
Korean phone call transcription pipeline with Whisper + speaker diarization, auto TODO/schedule/entity extraction, and Obsidian sync.
pip install korean-call-transcriber
# GPU support (transcription)
pip install korean-call-transcriber[gpu]
Features
- ๐๏ธ WhisperX Transcription โ faster-whisper (CTranslate2) for fast GPU-accelerated Korean speech-to-text
- ๐ฅ Speaker Diarization โ pyannote-based 2-speaker identification with Korean honorific heuristics
- ๐ Unified LLM Extraction โ Single API call extracts: Summary, TODOs, Appointments, Entities, Products, Money, Risks, and Corrections
- ๐ง STT Correction Layer โ Persistent exact replacements and alias normalization with hot-reload
- ๐ Gap Analyzer โ Deterministic pipeline health check with cause taxonomy
- ๐ Retry Queue โ JSONL-based atomic retry queue with exponential backoff
- ๐ Obsidian Sync โ Automatic transcript โ markdown conversion with counterparty indexing
- ๐ง Gmail Classifier โ Auto-classify inbox emails (ads โ trash, important โ highlight)
- ๐ Email TODO Extract โ Extract action items from incoming emails with LLM
- ๐ Calendar Integration โ Google Calendar event checking via OAuth2
- ๐ฌ SMS Pipeline โ Placeholder module for SMS-to-transcription integration
- ๐ฎ Naver Mail Archiver โ IMAP-based Naver Mail archiver with structured JSON output
- โ Persistent TODO Store โ Jaccard fuzzy-dedup, same-source merge, completed tracking
- ๐ง Knowledge Graph โ Entity relationship extraction and traversal (counterparty โ TODO โ event)
- ๐ก Signal Detector โ 3-band fast scoring + idea/entity extraction from any text
- โ๏ธ Minions Queue โ Postgres-backed durable job queue with fan-out, DAG, and crash recovery
- ๐ State Validator โ Automated state file existence, staleness, and integrity checks
โ ๏ธ Privacy Notice
This tool processes sensitive communications (calls, emails, SMS). Transcript text is sent to the configured LLM API for extraction โ all other processing runs locally. See PRIVACY.md for details and recommendations.
Module Status
| Module | Status | Notes |
|---|---|---|
| Transcription | Beta | WhisperX + diarization; GPU setup required |
| LLM Extraction | Beta | 8-category unified extraction; OpenAI-compatible API |
| STT Correction | Stable | Hot-reload rules |
| Obsidian Sync | Beta | Counterparty indexing; local vault paths required |
| Gmail Classifier | Experimental | Keyword-based classification; credentials required |
| Email TODO Extract | Experimental | LLM + rule-based; credentials required |
| Naver Mail | Experimental | IMAP archiving; Naver IMAP setup required |
| Calendar | Experimental | Google Calendar OAuth2 setup required |
| TODO Store | Stable | Jaccard fuzzy dedup |
| Knowledge Graph | Beta | Entity relationships |
| Signal Detector | Stable | 3-band fast scoring |
| Minions Queue | Beta | Postgres-backed; optional |
| State Validator | Stable | Integrity checks |
| SMS Handler | Placeholder | Integration pattern only |
| Retry Queue | Stable | JSONL + backoff |
Architecture
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ
โ Audio Files โโโโโโถโ batch_transcribe โโโโโโถโ Transcript .txt โ
โ (*.m4a) โ โ (WhisperX) โ โ โ
โโโโโโโโโโโโโโโโโโโ โ โโ transcribe โ โโโโโโโโโโฌโโโโโโโโโโ
โ โโ align โ โ
โ โโ diarize โ โ
โโโโโโโโโโโโโโโโโโโโ โ
โผ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ
โ Correction โโโโโโถโ extract_all โโโโโโถโ Structured Data โ
โ Layer โ โ (LLM) โ โ (JSON) โ
โโโโโโโโโโโโโโโโโโโ โ โโ summary โ โโโโโโโโโโโโโโโโโโโโ
โ โโ todos โ
โ โโ entities โ โโโโโโโโโโโโโโโโโโโโ
โ โโ products โโโโโโถโ Obsidian Vault โ
โ โโ risks โ โ (sync) โ
โโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Extended Pipeline (v0.5) โ
โ โ
โ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ
โ โ Gmail โ โ Email TODO โ โ Calendar โ โ
โ โ Classifier โ โ Extract โ โ Integration โ โ
โ โโโโโโโโฌโโโโโโโโ โโโโโโโโฌโโโโโโโโ โโโโโโโโฌโโโโโโโโ โ
โ โ โ โ โ
โ โผ โผ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Persistent TODO Store (Jaccard dedup) โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโ โ
โ โผ โผ โผ โ
โ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ
โ โ Knowledge โ โ Signal โ โ State โ โ
โ โ Graph โ โ Detector โ โ Validator โ โ
โ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ
โ โ
โ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ
โ โ Minions โ โ SMS Handler โ โ
โ โ Job Queue โ โ (placeholder)โ โ
โ โ (Postgres) โ โ โ โ
โ โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
See docs/architecture.md for detailed documentation.
Quick Start
Prerequisites
- Python 3.11+
- CUDA-capable GPU (tested on RTX 3090)
- ffmpeg in PATH
- HuggingFace token with pyannote access (for diarization)
- PostgreSQL 16+ (for Minions job queue โ optional)
Installation
# Clone and install (editable mode)
git clone https://github.com/brood-arch/korean-call-transcriber.git
cd korean-call-transcriber
# Basic development setup (no GPU deps)
pip install -e ".[dev]"
# With GPU transcription support (requires CUDA)
pip install -e ".[gpu,dev]"
# With Minions job queue (requires PostgreSQL + psycopg2)
pip install -e ".[queue,dev]"
# Everything
pip install -e ".[all,dev]"
See pyproject.toml [project.optional-dependencies] for available extras.
Usage
1. Transcribe audio files
# Transcribe all pending files
python -m kct.transcribe.batch_transcribe
# Transcribe a single file
python -m kct.transcribe.batch_transcribe --file path/to/audio.m4a
# Process newest files first
python -m kct.transcribe.batch_transcribe --recent-first --limit 10
# Equivalent installed CLI
kct-transcribe --recent-first --limit 10
2. Extract structured data
# Full extraction run (summary + todos + entities + ...)
python -m kct.extract.extract_all
# Dry run to validate setup
python -m kct.extract.extract_all --dry-run
# Process only today's files
python -m kct.extract.extract_all --today
# Equivalent installed CLI
kct-extract --today
3. Analyze pipeline health
# Check for gaps in the pipeline
python -m kct.queue.gap_analyzer
# Generate detailed report
python -m kct.queue.gap_analyzer --output-json report.json --output-md report.md
# Pipeline health shortcut
kct-health
4. Sync to Obsidian
# Sync new transcripts
python -m kct.sync.sync_obsidian
# Dry run
python -m kct.sync.sync_obsidian --dry-run
# Re-sync all files
python -m kct.sync.sync_obsidian --all
# Equivalent installed CLI
kct-sync-obsidian --all
5. Gmail auto-classification
# Set GMAIL_ADDRESS and GMAIL_APP_PASSWORD in .env first
python -m kct.integrations.gmail_classifier
6. Email TODO extraction
# Manage sender exclusion list
python -m kct.integrations.email_todo_extract exclude "newsletter@example.com"
python -m kct.integrations.email_todo_extract list-exclusions
python -m kct.integrations.email_todo_extract status
7. Calendar integration
# Set GCAL_TOKEN_PATH in .env to your OAuth2 token file
python -m kct.integrations.calendar
7.5. Naver Mail archiving
# Set NAVER_MAIL_ADDRESS and NAVER_MAIL_PASSWORD in .env first
# Enable IMAP in Naver Mail web settings
python -m kct.integrations.naver_mail
# Dry run (don't save state)
python -m kct.integrations.naver_mail --dry-run
# Single folder
python -m kct.integrations.naver_mail --folder INBOX --limit 50
8. Persistent TODO management
# Check status
python -m kct.todo.persistent_store status
# Sync completed TODOs
python -m kct.todo.persistent_store sync
9. Knowledge graph
# Build graph from all state sources
python -m kct.knowledge.graph --build
# Query related nodes
python -m kct.knowledge.graph --query "cp:CompanyName"
# Show statistics
python -m kct.knowledge.graph --stats
10. Signal detection
# Fast-score a text (no LLM needed)
python -m kct.knowledge.signal_detector --score "์ฃผ๋ฌธ 500๊ฐ ํ์ธํด์ฃผ์ธ์"
# Full signal detection
python -m kct.knowledge.signal_detector "Meeting with Acme about 500 units"
11. Minions job queue (requires PostgreSQL)
# Set MINIONS_DB_PASS in .env
python -m kct.pipeline.minions_queue submit sync_transcripts '{"cmd": "python -m kct.extract.extract_all"}'
python -m kct.pipeline.minions_queue list
python -m kct.pipeline.minions_queue stats
python -m kct.pipeline.minions_queue work
12. State validation
# Check all state files
python -m kct.pipeline.validate_state
# JSON output
python -m kct.pipeline.validate_state --json
# Quiet mode (only show issues)
python -m kct.pipeline.validate_state --quiet
Environment Variables
| Variable | Description | Default |
|---|---|---|
LLM_API_KEY |
LLM API key (ZAI_API_KEY is also supported for backward compatibility) |
(required) |
LLM_BASE_URL |
OpenAI-compatible API base URL (ZAI_BASE_URL is also supported) |
https://api.openai.com/v1 |
LLM_MODEL |
Model name | gpt-4o-mini |
LLM_DISABLE_THINKING |
Disable GLM thinking traces (auto, true, false) |
auto |
KCT_AUDIO_DIR |
Audio source directory (AUDIO_DIR is also supported for backward compatibility) |
data/audio |
KCT_TRANSCRIPT_DIR |
Transcript output directory (TRANSCRIPT_DIR is also supported for backward compatibility) |
output/transcripts |
WHISPER_MODEL |
faster-whisper model | mobiuslabsgmbh/faster-whisper-large-v3-turbo |
HF_TOKEN_FILE |
HuggingFace token file path | (empty) |
MY_NAME |
Speaker name for caller ID | Me |
GMAIL_ADDRESS |
Gmail address for IMAP login | (empty) |
GMAIL_APP_PASSWORD |
Gmail app-specific password | (empty) |
GCAL_TOKEN_PATH |
Path to Google Calendar OAuth2 token | state/gcal_token.json |
EMAIL_TODO_STATE |
Path to email TODO state file | state/email_todo_state.json |
EMAIL_TODO_EXCLUSIONS |
Path to sender exclusion list | state/email_todo_exclusions.json |
KCT_STATE_DIR |
Base state directory | state |
KCT_LOG_DIR |
Log directory | logs |
KCT_ENABLE_SHELL_JOBS |
Enable trusted local shell command payloads in Minions queue | 0 |
MINIONS_DB_HOST |
Minions Postgres host | localhost |
MINIONS_DB_PORT |
Minions Postgres port | 5432 |
MINIONS_DB_NAME |
Minions database name | minions |
MINIONS_DB_USER |
Minions database user | minions |
MINIONS_DB_PASS |
Minions database password | (required for queue) |
SMS_GATEWAY_URL |
SMS gateway API endpoint | (empty) |
SMS_API_KEY |
SMS gateway API key | (empty) |
NAVER_MAIL_ADDRESS |
Naver email address | (empty) |
NAVER_MAIL_PASSWORD |
Naver mail password or app password | (empty) |
NAVER_MAIL_HOST |
Naver IMAP host | imap.naver.com |
NAVER_MAIL_FOLDERS |
Comma-separated IMAP folders | INBOX,"Sent Messages" |
NAVER_MAIL_LIMIT |
Max messages per folder per run | 100 |
NAVER_MAIL_STATE_DIR |
State directory for processed UIDs | state/naver_mail |
See .env.example for the full list.
Additional operational notes:
Project Structure
kct/
โโโ transcribe/ # WhisperX transcription engine
โ โโโ batch_transcribe.py # Main batch transcription script
โ โโโ worker.py # Isolated subprocess worker
โ โโโ align_worker.py # Alignment + diarization worker
โโโ extract/ # LLM-based extraction
โ โโโ extract_all.py # Unified extraction (8 categories)
โ โโโ extract_entities.py # Standalone entity extraction
โ โโโ extract_schedules.py # Schedule/appointment extraction
โโโ correct/ # STT correction layer
โ โโโ corrections.py # Exact + alias corrections
โโโ sync/ # Output synchronization
โ โโโ sync_obsidian.py # Transcript โ Obsidian sync
โโโ pipeline/ # Shared utilities
โ โโโ paths.py # Central path configuration
โ โโโ utils.py # Common utilities
โ โโโ health_check.py # Pipeline health checks
โ โโโ minions_queue.py # Postgres-backed durable job queue
โ โโโ validate_state.py # State file validation
โโโ integrations/ # External service integrations
โ โโโ gmail_classifier.py # Gmail inbox auto-classifier
โ โโโ email_todo_extract.py # Email โ TODO extraction
โ โโโ calendar.py # Google Calendar integration
โ โโโ sms_handler.py # SMS pipeline placeholder
โ โโโ naver_mail.py # Naver Mail IMAP archiver
โโโ todo/ # TODO management
โ โโโ persistent_store.py # Persistent store with Jaccard dedup
โโโ knowledge/ # Knowledge graph & signal detection
โ โโโ graph.py # Entity relationship graph
โ โโโ signal_detector.py # 3-band fast scoring + signal detection
โโโ queue/ # Pipeline health & retry
โโโ gap_analyzer.py # Pipeline gap analysis
โโโ retry_queue.py # Atomic retry queue
Key Design Decisions
Process Isolation for DLL Safety
faster-whisper (CTranslate2) and whisperx (pyannote) have conflicting DLL requirements on Windows. The pipeline uses subprocess isolation: transcription runs in the main process, alignment and diarization run in a child process.
BatchedInferencePipeline
Uses BatchedInferencePipeline from faster-whisper for ~3x throughput improvement on NVIDIA GPUs, with automatic fallback to sequential mode.
Long Audio Chunking
Audio files longer than 5 minutes are automatically split into chunks to prevent CTranslate2 hard-kills on Windows. Timestamps are preserved across chunks.
Speaker Identification Heuristics
For 2-speaker Korean business calls, the pipeline uses multiple signals:
- Speech duration ratio
- Korean honorific detection (์ต๋๋ค, ์ ๋๋ค, ๋๋ฆฌ, etc.)
- First-speaker greeting analysis
Jaccard Fuzzy Dedup for TODOs
The persistent TODO store uses bigram Jaccard similarity (threshold โฅ 0.55) to prevent duplicate TODOs from being added across multiple extraction runs. Same-source dedup merges shorter titles into longer, more descriptive ones.
3-Band Signal Scoring
The signal detector uses a weighted multi-signal scoring system to pre-filter text before any LLM API call, saving tokens and latency on trivial messages.
Minions Job Queue
The Postgres-backed job queue provides crash recovery, idempotent submission, fan-out parallel execution with aggregators, and job steering via messages. Shell command payloads are disabled by default; set KCT_ENABLE_SHELL_JOBS=1 only for trusted local automation.
Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing) - Open a Pull Request
License
This project is licensed under the MIT License โ see the LICENSE file for details.
Changelog
v1.1.0
- Added Hermes active-runner orchestration for the full transcription pipeline.
- Added WSL/Windows workspace launcher scripts and operations dashboard documentation.
- Added extraction quality verification/re-extraction to the active-run sequence.
- Hardened retry queue locking, stale-lock reclaim, JSONL validation, and corrupt-state reporting.
- Updated active-run failure semantics so upstream failures block downstream stages by default and
partial_successexits non-zero.
v0.8.2
- Refactored
extract_entities.pyandextract_schedules.pyto use centralized LLM client (kct.extract.client) - Added logging to all silent
exceptblocks across codebase - Added
ffmpeg-pythonto core dependencies in pyproject.toml - Added
chromadbandobsidianoptional dependency groups - Created
docs/with security model, known limitations, and troubleshooting guides - Cleaned up
requirements.txtto match pyproject.toml
v0.3.4
- Centralized LLM configuration and reused the common LLM client across extraction modules
- Added sensitive-output redaction before retry/minions logs store stdout and stderr tails
- Disabled Minions shell command payloads by default unless
KCT_ENABLE_SHELL_JOBS=1 - Replaced duplicated signal detector implementation with a compatibility shim
- Reused centralized WSL detection and atomic write helpers across more runtime modules
- Preferred
KCT_*path environment variables while preserving legacy names
v0.3.3
- Added console entry points:
kct-transcribe,kct-extract,kct-health,kct-sync-obsidian - Generalized unified extraction client to prefer
LLM_API_KEY,LLM_BASE_URL, andLLM_MODEL - Made retry queue command tests robust across native Windows and WSL command shapes
- Switched CI linting to raw
ruff check . - Replaced over-broad module status labels with Stable/Beta/Experimental/Placeholder
v0.3.0
- Added
kct/integrations/โ Gmail classifier, email TODO extraction, calendar integration, SMS handler, Naver Mail archiver - Added
kct/todo/โ Persistent TODO store with Jaccard fuzzy dedup - Added
kct/knowledge/โ Knowledge graph builder and 3-band signal detector - Added
kct/pipeline/minions_queue.pyโ Postgres-backed durable job queue - Added
kct/pipeline/validate_state.pyโ State file validation - All personal data, passwords, and internal paths removed
v0.2.0
- STT correction layer with hot-reload
- Gap analyzer with cause taxonomy
- Retry queue with exponential backoff
v0.1.0
- Initial release: WhisperX transcription, LLM extraction, Obsidian sync
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file korean_call_transcriber-1.1.0.tar.gz.
File metadata
- Download URL: korean_call_transcriber-1.1.0.tar.gz
- Upload date:
- Size: 156.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6414657ec00160ea59d6ebd6da92cf747f80e1e966d0966190be4547c4ea777a
|
|
| MD5 |
ad427e6a6093bded9fbacb8638387854
|
|
| BLAKE2b-256 |
3ef4b1f7b560e94caf67033af86ebbafaacbbdc060c566bbd9a33dc9e7c2cabc
|
Provenance
The following attestation bundles were made for korean_call_transcriber-1.1.0.tar.gz:
Publisher:
publish.yml on brood-arch/korean-call-transcriber
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
korean_call_transcriber-1.1.0.tar.gz -
Subject digest:
6414657ec00160ea59d6ebd6da92cf747f80e1e966d0966190be4547c4ea777a - Sigstore transparency entry: 2110676422
- Sigstore integration time:
-
Permalink:
brood-arch/korean-call-transcriber@7b1266c2ceb41456fef90280c98d44917bf53c99 -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/brood-arch
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7b1266c2ceb41456fef90280c98d44917bf53c99 -
Trigger Event:
push
-
Statement type:
File details
Details for the file korean_call_transcriber-1.1.0-py3-none-any.whl.
File metadata
- Download URL: korean_call_transcriber-1.1.0-py3-none-any.whl
- Upload date:
- Size: 142.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8e45a5afa86d717898877f1df1510908b0f5706737a3c42a9b75fceb19c6ff31
|
|
| MD5 |
8d9cf165665cb87517dc396e683e4712
|
|
| BLAKE2b-256 |
ed4084aba14bb679fb83d4f94739166d42537aa408f65a6bac6ea658ee6e0336
|
Provenance
The following attestation bundles were made for korean_call_transcriber-1.1.0-py3-none-any.whl:
Publisher:
publish.yml on brood-arch/korean-call-transcriber
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
korean_call_transcriber-1.1.0-py3-none-any.whl -
Subject digest:
8e45a5afa86d717898877f1df1510908b0f5706737a3c42a9b75fceb19c6ff31 - Sigstore transparency entry: 2110676908
- Sigstore integration time:
-
Permalink:
brood-arch/korean-call-transcriber@7b1266c2ceb41456fef90280c98d44917bf53c99 -
Branch / Tag:
refs/tags/v1.1.0 - Owner: https://github.com/brood-arch
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7b1266c2ceb41456fef90280c98d44917bf53c99 -
Trigger Event:
push
-
Statement type: