enterprise-audio-intelligence / scripts /word_conversations_to_csv.py
Akbub's picture
deploy: Nexus AI v0.2.0 - SAP C4C Lead Creation UI included in fresh frontend build
d1f3f31
Raw
History Blame Contribute Delete
3.02 kB
from __future__ import annotations
import argparse
import csv
import re
from pathlib import Path
from docx import Document
ROLE_RX = re.compile(r"^\s*(?P<role>agent|customer|sales(?:person)?|user)\s*[:\-]\s*(?P<text>.+?)\s*$", re.IGNORECASE)
SPACE_RX = re.compile(r"\s+")
def normalize_text(value: str) -> str:
return SPACE_RX.sub(" ", value).strip()
def iter_docx_conversations(path: Path) -> list[dict[str, str]]:
document = Document(path)
rows: list[dict[str, str]] = []
current_turns: list[str] = []
conversation_index = 1
def flush() -> None:
nonlocal conversation_index, current_turns
text = normalize_text(" ".join(current_turns))
if text:
rows.append(
{
"file": f"{path.stem}_{conversation_index:03d}.docx",
"source_file": path.name,
"conversation_id": f"{path.stem}_{conversation_index:03d}",
"text": text,
}
)
conversation_index += 1
current_turns = []
for paragraph in document.paragraphs:
line = normalize_text(paragraph.text)
if not line:
flush()
continue
if line.lower().startswith(("conversation ", "call ", "transcript ")):
flush()
continue
match = ROLE_RX.match(line)
if match:
role = match.group("role").lower()
role = "Agent" if role in {"agent", "sales", "salesperson"} else "Customer"
current_turns.append(f"{role}: {match.group('text')}")
else:
current_turns.append(line)
flush()
return rows
def write_csv(rows: list[dict[str, str]], output: Path) -> None:
output.parent.mkdir(parents=True, exist_ok=True)
fieldnames = ["file", "source_file", "conversation_id", "text"]
with output.open("w", newline="", encoding="utf-8") as handle:
writer = csv.DictWriter(handle, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(rows)
def main() -> None:
parser = argparse.ArgumentParser(description="Convert Agent/Customer Word transcripts into a CSV for extraction benchmarking.")
parser.add_argument("input", type=Path, help="Path to one .docx file or a folder containing .docx files.")
parser.add_argument(
"--output",
type=Path,
default=Path("data/raw/word_conversations.csv"),
help="CSV output path. Defaults to data/raw/word_conversations.csv.",
)
args = parser.parse_args()
inputs = sorted(args.input.glob("*.docx")) if args.input.is_dir() else [args.input]
rows: list[dict[str, str]] = []
for path in inputs:
if path.suffix.lower() != ".docx":
raise SystemExit(f"Only .docx files are supported: {path}")
rows.extend(iter_docx_conversations(path))
write_csv(rows, args.output)
print(f"Wrote {len(rows)} conversation(s) to {args.output}")
if __name__ == "__main__":
main()