Skip to main content

conversation-analyser

Critical-thinking and analytics for human–AI conversations — a member of the analyser family.

It scores a single conversation on two tiers:

  1. Analytics (always on, offline): turn/word counts, prompt/response lengths, question ratio, pushback hits, readability, sentiment trajectory, prompt self-similarity, and temporal metrics when timestamps are present.
  2. Critical thinking (opt-in, needs an LLM): classifies every human turn under a 7-label prompt taxonomy, derives engagement ratios, an engagement band, and a composite 0–100 critical-thinking score with a component breakdown.

The taxonomy reuses the validated NQ/FU/CH/EX/DG/AC/MT scheme from the ISYS6020 marking pipeline (copied and forked). Design: docs/superpowers/specs/2026-05-23-conversation-analyser-design.md.

Install

pip install -e .                       # core: analytics + CLI + HTTP API
pip install -e '.[embeddings]'         # + prompt self-similarity (sentence-transformers)
pip install -e '.[llm]'                # + taxonomy/CT tier (anthropic)
pip install -e '.[embeddings,llm,dev]' # everything
export ANTHROPIC_API_KEY=...           # required for the critical-thinking tier

CLI

Bare positional path to analyse (human summary by default, --json for machines); serve subcommand for the HTTP API — same grammar as the rest of the family.

conversation-analyser transcript.txt              # human summary, analytics only
conversation-analyser chat.json --json            # full JSON to stdout
conversation-analyser chat.json --llm             # add the critical-thinking tier
conversation-analyser log.json --idle-gap 45      # split sub-sessions on 45-min gaps
conversation-analyser raw.txt --parse-mode llm-segment --llm
conversation-analyser serve --port 8009           # run the HTTP API

The critical-thinking tier is opt-in (--llm) to avoid surprise API costs; without it you get the analytics tier only.

HTTP API

conversation-analyser serve --port 8009
curl -F file=@chat.json 'http://127.0.0.1:8009/analyse'        # analytics only
curl -F file=@chat.json -F llm=true 'http://127.0.0.1:8009/analyse'
curl http://127.0.0.1:8009/health

GET /health and POST /analyse (multipart file upload, optional llm form field) — the same /analyse contract auto-analyser routes to.

Python API

from conversation_analyser import ConversationAnalyser

result = ConversationAnalyser().analyse("transcript.txt", llm=True)
print(result.model_dump_json(indent=2))

Input formats

A pluggable adapter registry tries, in order: structured adapters → heuristic speaker markers → optional LLM segmentation → unsegmented fallback.

  • role/content message list (OpenAI/Anthropic): [{"role": "user", "content": "..."}, ...]
  • AnythingLLM rows: [{"prompt": "...", "response": "...", "createdAt": ...}, ...]
  • flat text with speaker markers: User: / Assistant: / Me: / ChatGPT: / You said: / ChatGPT said: / Prompt: / Response:
  • anything else → LLM-segment (needs [llm]), else a single-blob fallback

.pdf/.docx inputs are text-extracted first (needs pdfplumber/markitdown, or pre-extract with document-analyser).

Long unstructured transcripts taking the LLM-segment path are split on paragraph boundaries into chunks (SEGMENT_CHUNK_CHARS, default 36 000) and classified chunk-by-chunk, so the whole transcript is labelled — not just its opening — and the band/ratios/score reflect all of it. The number of chunks (= LLM calls) is guarded by SEGMENT_MAX_CHUNKS (default 12); raise or lift it per run, e.g. CONVERSATION_ANALYSER_SEGMENT_MAX_CHUNKS=0 for unlimited. A capped run says so in notes rather than silently dropping the tail. Cleanly-labelled transcripts take the heuristic path and are never chunked.

The taxonomy

Code Meaning
NQ New Query — opens a new topic
FU Follow-up — clarification/elaboration
CH Challenge — pushes back, tests, asks why
EX Extension — applies/compares/synthesises in a new direction
DG Delegation — task hand-off, no engagement
AC Acknowledgement — thanks/confirmation
MT Meta — about the conversation itself

critical_thinking = (CH+EX)/turns, delegation = DG/turns, filler = (AC+MT)/turns. Bands: One-Shot · Delegator · Directed · Iterative · Critical.

Graceful degradation

Missing Effect
ANTHROPIC_API_KEY / [llm] taxonomy/critical_thinking null; analytics still produced; note llm_unavailable
[embeddings] prompt_self_similarity null; note embeddings_unavailable
timestamps temporal metrics omitted; no sub-session split; note no timestamps

Output

ConversationAnalysis → an aggregate (rolled up over all human turns, the headline) plus one SessionAnalysis per idle-gap sub-session, each with analytics, taxonomy, critical_thinking, and per-turn turns (label + rationale + preview). See the design spec §8 for the full schema.

Testing

pytest                    # fast, deterministic (LLM mocked, no network)
pytest -m slow            # includes sentence-transformers model download
pytest -m integration     # includes live LLM calls

Release files for conversation-analyser 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for conversation-analyser 0.5.0
File Size Uploaded
conversation_analyser-0.5.0.tar.gz 192.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for conversation-analyser 0.5.0
File Interpreter ABI Platform
conversation_analyser-0.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 223.7 kB

Release files / conversation_analyser-0.5.0.tar.gz

Download URL conversation_analyser-0.5.0.tar.gz
Size 192.6 kB
Tags Source
SHA-256 checksum
How to use checksums
bd9db9f0adea743d7f18e5066debc408c5dfd7a25be1c3cbf38eacae362683d9
BLAKE2b-256 checksum
How to use checksums
52316a023fc79231d6e36d908f61a0653c5a50e114566ed9ae2a74ee1808f37c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.0

Release files / conversation_analyser-0.5.0-py3-none-any.whl

Download URL conversation_analyser-0.5.0-py3-none-any.whl
Size 31.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
99259d9d0ebacbb59991b575b4c35fb35633e989e0b1f4380de6d2c31be59736
BLAKE2b-256 checksum
How to use checksums
0a945b45d3f3f6c48db104af6203e7980e9b7e84977fe0507bd415da8a0c665f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.0

Release history Release notifications | RSS feed

This release

0.5.0 This release

2 release files

0.4.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page