colloquial 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- colloquial-0.1.0/LICENSE +21 -0
- colloquial-0.1.0/PKG-INFO +244 -0
- colloquial-0.1.0/README.md +194 -0
- colloquial-0.1.0/pyproject.toml +114 -0
- colloquial-0.1.0/setup.cfg +4 -0
- colloquial-0.1.0/src/colloquial/__init__.py +3 -0
- colloquial-0.1.0/src/colloquial/__main__.py +4 -0
- colloquial-0.1.0/src/colloquial/cli.py +500 -0
- colloquial-0.1.0/src/colloquial/config.py +192 -0
- colloquial-0.1.0/src/colloquial/core/__init__.py +1 -0
- colloquial-0.1.0/src/colloquial/core/detect.py +121 -0
- colloquial-0.1.0/src/colloquial/core/discourse.py +4538 -0
- colloquial-0.1.0/src/colloquial/core/diversity.py +136 -0
- colloquial-0.1.0/src/colloquial/core/langdetect.py +46 -0
- colloquial-0.1.0/src/colloquial/core/report.py +173 -0
- colloquial-0.1.0/src/colloquial/core/stats.py +119 -0
- colloquial-0.1.0/src/colloquial/core/surface.py +621 -0
- colloquial-0.1.0/src/colloquial/langs/__init__.py +7 -0
- colloquial-0.1.0/src/colloquial/mcp.py +326 -0
- colloquial-0.1.0/src/colloquial/providers.py +195 -0
- colloquial-0.1.0/src/colloquial/rewrite/__init__.py +1 -0
- colloquial-0.1.0/src/colloquial/rewrite/engine.py +200 -0
- colloquial-0.1.0/src/colloquial/rewrite/llm.py +140 -0
- colloquial-0.1.0/src/colloquial/rewrite/mechanical.py +840 -0
- colloquial-0.1.0/src/colloquial/style/ar.md +74 -0
- colloquial-0.1.0/src/colloquial/style/en.md +101 -0
- colloquial-0.1.0/src/colloquial/style/hi.md +53 -0
- colloquial-0.1.0/src/colloquial/style/ja.md +45 -0
- colloquial-0.1.0/src/colloquial/style/ko.md +109 -0
- colloquial-0.1.0/src/colloquial/style/pt-br.md +103 -0
- colloquial-0.1.0/src/colloquial/style/uk.md +59 -0
- colloquial-0.1.0/src/colloquial/style/zh.md +51 -0
- colloquial-0.1.0/src/colloquial.egg-info/PKG-INFO +244 -0
- colloquial-0.1.0/src/colloquial.egg-info/SOURCES.txt +53 -0
- colloquial-0.1.0/src/colloquial.egg-info/dependency_links.txt +1 -0
- colloquial-0.1.0/src/colloquial.egg-info/entry_points.txt +2 -0
- colloquial-0.1.0/src/colloquial.egg-info/requires.txt +9 -0
- colloquial-0.1.0/src/colloquial.egg-info/top_level.txt +1 -0
- colloquial-0.1.0/tests/test_arabic.py +153 -0
- colloquial-0.1.0/tests/test_cli.py +542 -0
- colloquial-0.1.0/tests/test_cli_setup.py +103 -0
- colloquial-0.1.0/tests/test_config.py +127 -0
- colloquial-0.1.0/tests/test_coverage_branches.py +164 -0
- colloquial-0.1.0/tests/test_detect.py +99 -0
- colloquial-0.1.0/tests/test_discourse.py +165 -0
- colloquial-0.1.0/tests/test_diversity.py +106 -0
- colloquial-0.1.0/tests/test_entrypoint.py +47 -0
- colloquial-0.1.0/tests/test_langs_m4.py +170 -0
- colloquial-0.1.0/tests/test_llm.py +191 -0
- colloquial-0.1.0/tests/test_mcp.py +333 -0
- colloquial-0.1.0/tests/test_providers.py +60 -0
- colloquial-0.1.0/tests/test_report.py +87 -0
- colloquial-0.1.0/tests/test_rewrite.py +366 -0
- colloquial-0.1.0/tests/test_stats.py +64 -0
- colloquial-0.1.0/tests/test_translate.py +111 -0
colloquial-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Robert (XScryer)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: colloquial
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Rewrite machine text into colloquial, native-sounding language — humanize in the same language or translate-and-humanize, in any tongue.
|
|
5
|
+
Author: XScryer
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 Robert (XScryer)
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Project-URL: Homepage, https://github.com/XScryer/colloquial
|
|
29
|
+
Project-URL: Repository, https://github.com/XScryer/colloquial
|
|
30
|
+
Project-URL: Issues, https://github.com/XScryer/colloquial/issues
|
|
31
|
+
Project-URL: Changelog, https://github.com/XScryer/colloquial/blob/main/CHANGELOG.md
|
|
32
|
+
Keywords: nlp,writing,humanize,translation,llm,slop
|
|
33
|
+
Classifier: Development Status :: 3 - Alpha
|
|
34
|
+
Classifier: Intended Audience :: Developers
|
|
35
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
36
|
+
Classifier: Programming Language :: Python :: 3
|
|
37
|
+
Classifier: Topic :: Text Processing :: Linguistic
|
|
38
|
+
Requires-Python: >=3.10
|
|
39
|
+
Description-Content-Type: text/markdown
|
|
40
|
+
License-File: LICENSE
|
|
41
|
+
Provides-Extra: dev
|
|
42
|
+
Requires-Dist: bandit>=1.7; extra == "dev"
|
|
43
|
+
Requires-Dist: mypy>=1.10; extra == "dev"
|
|
44
|
+
Requires-Dist: pip-audit>=2.7; extra == "dev"
|
|
45
|
+
Requires-Dist: pre-commit>=3.7; extra == "dev"
|
|
46
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
47
|
+
Requires-Dist: pytest-cov>=5; extra == "dev"
|
|
48
|
+
Requires-Dist: ruff>=0.6; extra == "dev"
|
|
49
|
+
Dynamic: license-file
|
|
50
|
+
|
|
51
|
+
# Colloquial
|
|
52
|
+
|
|
53
|
+
Rewrite machine text into colloquial, native-sounding language, in any tongue.
|
|
54
|
+
|
|
55
|
+
Colloquial takes text written by an LLM and produces text that reads like a
|
|
56
|
+
person wrote it. It works in the same language (`--same-lang`) or translates and
|
|
57
|
+
humanizes in one pass (`--to <lang>`). A deterministic detection core (no
|
|
58
|
+
network, no LLM) scores how machine a text sounds, a report ranks the worst
|
|
59
|
+
sections first, and an optional self-check loop re-evaluates the output.
|
|
60
|
+
|
|
61
|
+
The name says it. Colloquial. How people actually talk and write.
|
|
62
|
+
|
|
63
|
+
## Why this exists
|
|
64
|
+
|
|
65
|
+
Machine-written prose has a signature, and it is not just word choice. Research
|
|
66
|
+
on 61,608 stories (StoryScope, COLM 2026) shows that narrative features alone
|
|
67
|
+
separate human from machine text at 93.2% macro-F1, and that these structural
|
|
68
|
+
patterns survive paraphrasing. Surface detectors break when the wording
|
|
69
|
+
changes. The structure does not.
|
|
70
|
+
|
|
71
|
+
Colloquial is built on that finding. It reads how a text is built and rewrites
|
|
72
|
+
it the way a person would have built it. The result is not text with words
|
|
73
|
+
swapped. It is text with a different skeleton.
|
|
74
|
+
|
|
75
|
+
## What it does
|
|
76
|
+
|
|
77
|
+
| Command | What you get |
|
|
78
|
+
|---|---|
|
|
79
|
+
| `colloquial detect FILE` | A machine-likeness score from 0 to 100, ranked findings, and the worst sections first |
|
|
80
|
+
| `colloquial humanize FILE` | A rewrite that reads human, in the same language, offline and deterministic |
|
|
81
|
+
| `colloquial humanize FILE --mode llm` | The same rewrite driven by your own model, with a style profile built from the research |
|
|
82
|
+
| `colloquial humanize FILE --to ar` | Translate and humanize in one pass, without translationese |
|
|
83
|
+
| `colloquial humanize FILE --self-check` | Re-detect the output and iterate when it still reads machine-made |
|
|
84
|
+
| `colloquial mcp` | The engine as an MCP server, for Claude Code, Codex, Cursor and Hermes |
|
|
85
|
+
|
|
86
|
+
## How it works
|
|
87
|
+
|
|
88
|
+
Five layers, cheapest first. Each one feeds the next, and every layer is
|
|
89
|
+
grounded in published measurements.
|
|
90
|
+
|
|
91
|
+
1. **Surface rules.** Filler transitions, inflated significance, machine
|
|
92
|
+
punctuation, AI self-reference. Hundreds of rules across eight languages.
|
|
93
|
+
This layer is deliberately the weakest, because wordlists alone produce
|
|
94
|
+
false positives on legitimate human text.
|
|
95
|
+
2. **Rhythm.** Burstiness (the coefficient of variation of sentence length),
|
|
96
|
+
type-token ratio, trigram repetition. Machine text keeps an even tempo.
|
|
97
|
+
People do not.
|
|
98
|
+
3. **Lexical diversity.** Six dimensions from arXiv 2508.00086, including
|
|
99
|
+
dispersion (how close repeated words sit) and evenness (how uniformly
|
|
100
|
+
vocabulary spreads). The counter-intuitive finding of that paper is that
|
|
101
|
+
machine text is *more* lexically varied than human text and repeats words
|
|
102
|
+
at *longer* distances. Dispersion alone carries a SHAP weight of 0.279,
|
|
103
|
+
the strongest single discriminator measured.
|
|
104
|
+
4. **Discourse.** A ten-dimension narrative profile ported from StoryScope
|
|
105
|
+
(revelation, events, perspective, plot, setting, style, situatedness,
|
|
106
|
+
temporal structure, agents, social networks). It measures how the text is
|
|
107
|
+
constructed, not what words it uses, and it produces a soft per-model
|
|
108
|
+
fingerprint (Claude-like flat escalation, GPT-like gossip as plot
|
|
109
|
+
mechanism, Gemini-like external description) on texts above 300 words.
|
|
110
|
+
5. **Persona.** AI-assisted writing makes the writer seem more confident, more
|
|
111
|
+
positive and more privileged than they are (arXiv 2604.22503). This layer
|
|
112
|
+
strips the tells and keeps the writer's actual voice.
|
|
113
|
+
|
|
114
|
+
The mechanical rewriter reverses what the detector finds, offline. The LLM
|
|
115
|
+
rewriter sends the text with a style profile built from the same research, so
|
|
116
|
+
either way the rules behind the rewrite are the same rules behind the score.
|
|
117
|
+
|
|
118
|
+
## The science behind it
|
|
119
|
+
|
|
120
|
+
Colloquial is not a prompt pack with a CLI glued on. Every layer cites its
|
|
121
|
+
source, and the sources are peer-reviewed.
|
|
122
|
+
|
|
123
|
+
| Source | What it contributed |
|
|
124
|
+
|---|---|
|
|
125
|
+
| **StoryScope** (arXiv 2604.03136, COLM 2026) | The ten discourse dimensions, the per-model fingerprints, and the finding that structural features survive paraphrasing (93.2% macro-F1 on 61,608 stories) |
|
|
126
|
+
| **Lexical diversity** (arXiv 2508.00086) | The six diversity dimensions and their AI/human directions; dispersion as the strongest discriminator |
|
|
127
|
+
| **AI Argues Differently** (arXiv 2604.22503, EMNLP 2025) | The persona-distortion catalog: over-confidence, forced positivity, compressed emotional range |
|
|
128
|
+
| **The Arabic AI Fingerprint** (arXiv 2505.23276, KFUPM) | Arabic stylometric tells: overused high-frequency words, lower vocabulary spread, domain-specific signatures |
|
|
129
|
+
| **Falsely Accused** (arXiv 2511.16690) | The calibration lesson: detectors misjudge slightly-polished Arabic (92% to 12% accuracy on polished text), so the Arabic profile fails open instead of accusing |
|
|
130
|
+
| **"Signs of AI writing"** (Wikipedia, WikiProject AI Cleanup) | The shared heritage behind the surface rule sets |
|
|
131
|
+
|
|
132
|
+
Two design commitments follow from the research. First, detection is
|
|
133
|
+
deterministic and offline, so a score is reproducible and a rewrite never
|
|
134
|
+
depends on a network call. Second, the tool fails open. It prefers a missed
|
|
135
|
+
detection to a false accusation, because the real cost of an AI detector is
|
|
136
|
+
sending a human's honest text back to them marked as machine-made.
|
|
137
|
+
|
|
138
|
+
## What makes it different
|
|
139
|
+
|
|
140
|
+
An honest comparison with the tools that came before.
|
|
141
|
+
|
|
142
|
+
- **Eight languages with real machinery.** English, Portuguese (Brazil),
|
|
143
|
+
Arabic (neutral MSA), Chinese, Japanese, Korean, Hindi and Ukrainian. Each
|
|
144
|
+
language ships its own surface rules, discourse lexicons, style profile and
|
|
145
|
+
rewrite transforms. The Arabic profile includes a dialect-consistency lock.
|
|
146
|
+
Egyptian, Levantine, Gulf, Maghrebi and Iraqi markers are rewritten to
|
|
147
|
+
neutral MSA, so a text never comes back as a dialectal mix. The Ukrainian
|
|
148
|
+
profile does the same for Russian calques, known as surzhyk.
|
|
149
|
+
- **Discourse, not just vocabulary.** Most humanizers work at the word level.
|
|
150
|
+
Colloquial reads event escalation, dialogue balance, theme explicitness and
|
|
151
|
+
temporal texture, because that is where the research says the signal lives.
|
|
152
|
+
- **Per-model fingerprints.** The report says which family the text resembles.
|
|
153
|
+
This is a soft signal, never a verdict.
|
|
154
|
+
- **Two rewrite paths from one rulebook.** The offline path needs no key, no
|
|
155
|
+
account and no network. The LLM path uses whatever provider the user
|
|
156
|
+
configures, and both are judged by the same detector.
|
|
157
|
+
- **Zero runtime dependencies.** Standard library only, by design. The quality
|
|
158
|
+
wall (ruff, mypy strict, bandit, pytest at 80% coverage minimum) runs on
|
|
159
|
+
every push in CI.
|
|
160
|
+
|
|
161
|
+
## Install
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
pip install colloquial
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Or run it without installing anything:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
uvx colloquial detect README.md
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Quick start
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
colloquial detect README.md
|
|
177
|
+
colloquial detect docs/ --report --format json
|
|
178
|
+
colloquial humanize draft.md --lang pt-br --report
|
|
179
|
+
colloquial humanize draft.md --mode llm --self-check
|
|
180
|
+
colloquial humanize draft.md --to ar
|
|
181
|
+
colloquial langs
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## Using it from coding agents (MCP)
|
|
185
|
+
|
|
186
|
+
Colloquial runs as an MCP server, so any MCP-capable agent (Claude Code,
|
|
187
|
+
Codex, Cursor, Cline, Hermes) can call it as native tools.
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
colloquial mcp
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Tools: `detect_text`, `humanize_text`, `translate_humanize`, `list_languages`,
|
|
194
|
+
`get_report`. See [docs/plugins.md](docs/plugins.md) for per-agent setup, and
|
|
195
|
+
`skills/` for ready-made skill files.
|
|
196
|
+
|
|
197
|
+
## Choosing a provider (llm mode)
|
|
198
|
+
|
|
199
|
+
The mechanical rewriter is offline and needs nothing. The `--mode llm`
|
|
200
|
+
rewriter runs against any OpenAI-compatible API, and the provider is always
|
|
201
|
+
your choice. Your key, your model, your machine.
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
colloquial providers # see the catalog
|
|
205
|
+
colloquial setup # interactive: pick provider, key, model
|
|
206
|
+
colloquial models # live model list from your provider
|
|
207
|
+
colloquial config # show the resolved configuration
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
`colloquial setup` writes `~/.config/colloquial/config.toml` (mode 0600).
|
|
211
|
+
It queries the provider's live `/models` endpoint with your key, so the
|
|
212
|
+
model list is always current. Local providers (Ollama, vLLM, llama.cpp,
|
|
213
|
+
LM Studio) need no key at all.
|
|
214
|
+
|
|
215
|
+
The catalog covers OpenAI, Anthropic (Claude), Google Gemini, xAI (Grok),
|
|
216
|
+
Mistral, DeepSeek, Groq, Cerebras, MiniMax, Moonshot (Kimi), Z.ai (GLM),
|
|
217
|
+
Alibaba Qwen, Nous Research, OpenRouter, Together AI, Fireworks AI, and
|
|
218
|
+
the local servers above, plus a `custom` entry for any other
|
|
219
|
+
OpenAI-compatible endpoint.
|
|
220
|
+
|
|
221
|
+
Environment variables still work and take precedence over the config file:
|
|
222
|
+
`COLLOQUIAL_PROVIDER`, `COLLOQUIAL_API_KEY` (or `OPENAI_API_KEY`),
|
|
223
|
+
`COLLOQUIAL_BASE_URL`, `COLLOQUIAL_MODEL`.
|
|
224
|
+
|
|
225
|
+
## Supported languages
|
|
226
|
+
|
|
227
|
+
English (en) · Arabic (ar, neutral MSA) · Chinese (zh) · Japanese (ja) ·
|
|
228
|
+
Korean (ko) · Hindi (hi) · Ukrainian (uk) · Portuguese (pt-BR)
|
|
229
|
+
|
|
230
|
+
The Arabic, Chinese, Japanese, Korean, Hindi and Ukrainian profiles ship as
|
|
231
|
+
community-validated beta. Their rule sets were researched against public
|
|
232
|
+
sources but deserve review from native speakers. Pull requests that sharpen a
|
|
233
|
+
lexicon, add a tell, or fix a false positive are the most valuable
|
|
234
|
+
contribution this project can receive.
|
|
235
|
+
|
|
236
|
+
## Contributing
|
|
237
|
+
|
|
238
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md). The short version is that every change
|
|
239
|
+
runs through the quality wall, and language profiles need a minimum test
|
|
240
|
+
corpus.
|
|
241
|
+
|
|
242
|
+
## License
|
|
243
|
+
|
|
244
|
+
MIT
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# Colloquial
|
|
2
|
+
|
|
3
|
+
Rewrite machine text into colloquial, native-sounding language, in any tongue.
|
|
4
|
+
|
|
5
|
+
Colloquial takes text written by an LLM and produces text that reads like a
|
|
6
|
+
person wrote it. It works in the same language (`--same-lang`) or translates and
|
|
7
|
+
humanizes in one pass (`--to <lang>`). A deterministic detection core (no
|
|
8
|
+
network, no LLM) scores how machine a text sounds, a report ranks the worst
|
|
9
|
+
sections first, and an optional self-check loop re-evaluates the output.
|
|
10
|
+
|
|
11
|
+
The name says it. Colloquial. How people actually talk and write.
|
|
12
|
+
|
|
13
|
+
## Why this exists
|
|
14
|
+
|
|
15
|
+
Machine-written prose has a signature, and it is not just word choice. Research
|
|
16
|
+
on 61,608 stories (StoryScope, COLM 2026) shows that narrative features alone
|
|
17
|
+
separate human from machine text at 93.2% macro-F1, and that these structural
|
|
18
|
+
patterns survive paraphrasing. Surface detectors break when the wording
|
|
19
|
+
changes. The structure does not.
|
|
20
|
+
|
|
21
|
+
Colloquial is built on that finding. It reads how a text is built and rewrites
|
|
22
|
+
it the way a person would have built it. The result is not text with words
|
|
23
|
+
swapped. It is text with a different skeleton.
|
|
24
|
+
|
|
25
|
+
## What it does
|
|
26
|
+
|
|
27
|
+
| Command | What you get |
|
|
28
|
+
|---|---|
|
|
29
|
+
| `colloquial detect FILE` | A machine-likeness score from 0 to 100, ranked findings, and the worst sections first |
|
|
30
|
+
| `colloquial humanize FILE` | A rewrite that reads human, in the same language, offline and deterministic |
|
|
31
|
+
| `colloquial humanize FILE --mode llm` | The same rewrite driven by your own model, with a style profile built from the research |
|
|
32
|
+
| `colloquial humanize FILE --to ar` | Translate and humanize in one pass, without translationese |
|
|
33
|
+
| `colloquial humanize FILE --self-check` | Re-detect the output and iterate when it still reads machine-made |
|
|
34
|
+
| `colloquial mcp` | The engine as an MCP server, for Claude Code, Codex, Cursor and Hermes |
|
|
35
|
+
|
|
36
|
+
## How it works
|
|
37
|
+
|
|
38
|
+
Five layers, cheapest first. Each one feeds the next, and every layer is
|
|
39
|
+
grounded in published measurements.
|
|
40
|
+
|
|
41
|
+
1. **Surface rules.** Filler transitions, inflated significance, machine
|
|
42
|
+
punctuation, AI self-reference. Hundreds of rules across eight languages.
|
|
43
|
+
This layer is deliberately the weakest, because wordlists alone produce
|
|
44
|
+
false positives on legitimate human text.
|
|
45
|
+
2. **Rhythm.** Burstiness (the coefficient of variation of sentence length),
|
|
46
|
+
type-token ratio, trigram repetition. Machine text keeps an even tempo.
|
|
47
|
+
People do not.
|
|
48
|
+
3. **Lexical diversity.** Six dimensions from arXiv 2508.00086, including
|
|
49
|
+
dispersion (how close repeated words sit) and evenness (how uniformly
|
|
50
|
+
vocabulary spreads). The counter-intuitive finding of that paper is that
|
|
51
|
+
machine text is *more* lexically varied than human text and repeats words
|
|
52
|
+
at *longer* distances. Dispersion alone carries a SHAP weight of 0.279,
|
|
53
|
+
the strongest single discriminator measured.
|
|
54
|
+
4. **Discourse.** A ten-dimension narrative profile ported from StoryScope
|
|
55
|
+
(revelation, events, perspective, plot, setting, style, situatedness,
|
|
56
|
+
temporal structure, agents, social networks). It measures how the text is
|
|
57
|
+
constructed, not what words it uses, and it produces a soft per-model
|
|
58
|
+
fingerprint (Claude-like flat escalation, GPT-like gossip as plot
|
|
59
|
+
mechanism, Gemini-like external description) on texts above 300 words.
|
|
60
|
+
5. **Persona.** AI-assisted writing makes the writer seem more confident, more
|
|
61
|
+
positive and more privileged than they are (arXiv 2604.22503). This layer
|
|
62
|
+
strips the tells and keeps the writer's actual voice.
|
|
63
|
+
|
|
64
|
+
The mechanical rewriter reverses what the detector finds, offline. The LLM
|
|
65
|
+
rewriter sends the text with a style profile built from the same research, so
|
|
66
|
+
either way the rules behind the rewrite are the same rules behind the score.
|
|
67
|
+
|
|
68
|
+
## The science behind it
|
|
69
|
+
|
|
70
|
+
Colloquial is not a prompt pack with a CLI glued on. Every layer cites its
|
|
71
|
+
source, and the sources are peer-reviewed.
|
|
72
|
+
|
|
73
|
+
| Source | What it contributed |
|
|
74
|
+
|---|---|
|
|
75
|
+
| **StoryScope** (arXiv 2604.03136, COLM 2026) | The ten discourse dimensions, the per-model fingerprints, and the finding that structural features survive paraphrasing (93.2% macro-F1 on 61,608 stories) |
|
|
76
|
+
| **Lexical diversity** (arXiv 2508.00086) | The six diversity dimensions and their AI/human directions; dispersion as the strongest discriminator |
|
|
77
|
+
| **AI Argues Differently** (arXiv 2604.22503, EMNLP 2025) | The persona-distortion catalog: over-confidence, forced positivity, compressed emotional range |
|
|
78
|
+
| **The Arabic AI Fingerprint** (arXiv 2505.23276, KFUPM) | Arabic stylometric tells: overused high-frequency words, lower vocabulary spread, domain-specific signatures |
|
|
79
|
+
| **Falsely Accused** (arXiv 2511.16690) | The calibration lesson: detectors misjudge slightly-polished Arabic (92% to 12% accuracy on polished text), so the Arabic profile fails open instead of accusing |
|
|
80
|
+
| **"Signs of AI writing"** (Wikipedia, WikiProject AI Cleanup) | The shared heritage behind the surface rule sets |
|
|
81
|
+
|
|
82
|
+
Two design commitments follow from the research. First, detection is
|
|
83
|
+
deterministic and offline, so a score is reproducible and a rewrite never
|
|
84
|
+
depends on a network call. Second, the tool fails open. It prefers a missed
|
|
85
|
+
detection to a false accusation, because the real cost of an AI detector is
|
|
86
|
+
sending a human's honest text back to them marked as machine-made.
|
|
87
|
+
|
|
88
|
+
## What makes it different
|
|
89
|
+
|
|
90
|
+
An honest comparison with the tools that came before.
|
|
91
|
+
|
|
92
|
+
- **Eight languages with real machinery.** English, Portuguese (Brazil),
|
|
93
|
+
Arabic (neutral MSA), Chinese, Japanese, Korean, Hindi and Ukrainian. Each
|
|
94
|
+
language ships its own surface rules, discourse lexicons, style profile and
|
|
95
|
+
rewrite transforms. The Arabic profile includes a dialect-consistency lock.
|
|
96
|
+
Egyptian, Levantine, Gulf, Maghrebi and Iraqi markers are rewritten to
|
|
97
|
+
neutral MSA, so a text never comes back as a dialectal mix. The Ukrainian
|
|
98
|
+
profile does the same for Russian calques, known as surzhyk.
|
|
99
|
+
- **Discourse, not just vocabulary.** Most humanizers work at the word level.
|
|
100
|
+
Colloquial reads event escalation, dialogue balance, theme explicitness and
|
|
101
|
+
temporal texture, because that is where the research says the signal lives.
|
|
102
|
+
- **Per-model fingerprints.** The report says which family the text resembles.
|
|
103
|
+
This is a soft signal, never a verdict.
|
|
104
|
+
- **Two rewrite paths from one rulebook.** The offline path needs no key, no
|
|
105
|
+
account and no network. The LLM path uses whatever provider the user
|
|
106
|
+
configures, and both are judged by the same detector.
|
|
107
|
+
- **Zero runtime dependencies.** Standard library only, by design. The quality
|
|
108
|
+
wall (ruff, mypy strict, bandit, pytest at 80% coverage minimum) runs on
|
|
109
|
+
every push in CI.
|
|
110
|
+
|
|
111
|
+
## Install
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
pip install colloquial
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Or run it without installing anything:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
uvx colloquial detect README.md
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Quick start
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
colloquial detect README.md
|
|
127
|
+
colloquial detect docs/ --report --format json
|
|
128
|
+
colloquial humanize draft.md --lang pt-br --report
|
|
129
|
+
colloquial humanize draft.md --mode llm --self-check
|
|
130
|
+
colloquial humanize draft.md --to ar
|
|
131
|
+
colloquial langs
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Using it from coding agents (MCP)
|
|
135
|
+
|
|
136
|
+
Colloquial runs as an MCP server, so any MCP-capable agent (Claude Code,
|
|
137
|
+
Codex, Cursor, Cline, Hermes) can call it as native tools.
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
colloquial mcp
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Tools: `detect_text`, `humanize_text`, `translate_humanize`, `list_languages`,
|
|
144
|
+
`get_report`. See [docs/plugins.md](docs/plugins.md) for per-agent setup, and
|
|
145
|
+
`skills/` for ready-made skill files.
|
|
146
|
+
|
|
147
|
+
## Choosing a provider (llm mode)
|
|
148
|
+
|
|
149
|
+
The mechanical rewriter is offline and needs nothing. The `--mode llm`
|
|
150
|
+
rewriter runs against any OpenAI-compatible API, and the provider is always
|
|
151
|
+
your choice. Your key, your model, your machine.
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
colloquial providers # see the catalog
|
|
155
|
+
colloquial setup # interactive: pick provider, key, model
|
|
156
|
+
colloquial models # live model list from your provider
|
|
157
|
+
colloquial config # show the resolved configuration
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
`colloquial setup` writes `~/.config/colloquial/config.toml` (mode 0600).
|
|
161
|
+
It queries the provider's live `/models` endpoint with your key, so the
|
|
162
|
+
model list is always current. Local providers (Ollama, vLLM, llama.cpp,
|
|
163
|
+
LM Studio) need no key at all.
|
|
164
|
+
|
|
165
|
+
The catalog covers OpenAI, Anthropic (Claude), Google Gemini, xAI (Grok),
|
|
166
|
+
Mistral, DeepSeek, Groq, Cerebras, MiniMax, Moonshot (Kimi), Z.ai (GLM),
|
|
167
|
+
Alibaba Qwen, Nous Research, OpenRouter, Together AI, Fireworks AI, and
|
|
168
|
+
the local servers above, plus a `custom` entry for any other
|
|
169
|
+
OpenAI-compatible endpoint.
|
|
170
|
+
|
|
171
|
+
Environment variables still work and take precedence over the config file:
|
|
172
|
+
`COLLOQUIAL_PROVIDER`, `COLLOQUIAL_API_KEY` (or `OPENAI_API_KEY`),
|
|
173
|
+
`COLLOQUIAL_BASE_URL`, `COLLOQUIAL_MODEL`.
|
|
174
|
+
|
|
175
|
+
## Supported languages
|
|
176
|
+
|
|
177
|
+
English (en) · Arabic (ar, neutral MSA) · Chinese (zh) · Japanese (ja) ·
|
|
178
|
+
Korean (ko) · Hindi (hi) · Ukrainian (uk) · Portuguese (pt-BR)
|
|
179
|
+
|
|
180
|
+
The Arabic, Chinese, Japanese, Korean, Hindi and Ukrainian profiles ship as
|
|
181
|
+
community-validated beta. Their rule sets were researched against public
|
|
182
|
+
sources but deserve review from native speakers. Pull requests that sharpen a
|
|
183
|
+
lexicon, add a tell, or fix a false positive are the most valuable
|
|
184
|
+
contribution this project can receive.
|
|
185
|
+
|
|
186
|
+
## Contributing
|
|
187
|
+
|
|
188
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md). The short version is that every change
|
|
189
|
+
runs through the quality wall, and language profiles need a minimum test
|
|
190
|
+
corpus.
|
|
191
|
+
|
|
192
|
+
## License
|
|
193
|
+
|
|
194
|
+
MIT
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "colloquial"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Rewrite machine text into colloquial, native-sounding language — humanize in the same language or translate-and-humanize, in any tongue."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = { file = "LICENSE" }
|
|
12
|
+
authors = [{ name = "XScryer" }]
|
|
13
|
+
keywords = ["nlp", "writing", "humanize", "translation", "llm", "slop"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 3 - Alpha",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Topic :: Text Processing :: Linguistic",
|
|
20
|
+
]
|
|
21
|
+
dependencies = []
|
|
22
|
+
|
|
23
|
+
[project.urls]
|
|
24
|
+
Homepage = "https://github.com/XScryer/colloquial"
|
|
25
|
+
Repository = "https://github.com/XScryer/colloquial"
|
|
26
|
+
Issues = "https://github.com/XScryer/colloquial/issues"
|
|
27
|
+
Changelog = "https://github.com/XScryer/colloquial/blob/main/CHANGELOG.md"
|
|
28
|
+
|
|
29
|
+
[project.optional-dependencies]
|
|
30
|
+
dev = [
|
|
31
|
+
"bandit>=1.7",
|
|
32
|
+
"mypy>=1.10",
|
|
33
|
+
"pip-audit>=2.7",
|
|
34
|
+
"pre-commit>=3.7",
|
|
35
|
+
"pytest>=8",
|
|
36
|
+
"pytest-cov>=5",
|
|
37
|
+
"ruff>=0.6",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
[project.scripts]
|
|
41
|
+
colloquial = "colloquial.cli:main"
|
|
42
|
+
|
|
43
|
+
[tool.setuptools.packages.find]
|
|
44
|
+
where = ["src"]
|
|
45
|
+
|
|
46
|
+
[tool.setuptools.package-data]
|
|
47
|
+
colloquial = ["style/*.md"]
|
|
48
|
+
|
|
49
|
+
[tool.ruff]
|
|
50
|
+
line-length = 100
|
|
51
|
+
target-version = "py310"
|
|
52
|
+
src = ["src", "tests"]
|
|
53
|
+
|
|
54
|
+
[tool.ruff.lint]
|
|
55
|
+
select = [
|
|
56
|
+
"E",
|
|
57
|
+
"W",
|
|
58
|
+
"F",
|
|
59
|
+
"I",
|
|
60
|
+
"UP",
|
|
61
|
+
"B",
|
|
62
|
+
"SIM",
|
|
63
|
+
"C4",
|
|
64
|
+
"RUF",
|
|
65
|
+
"PERF",
|
|
66
|
+
"ASYNC",
|
|
67
|
+
"S",
|
|
68
|
+
"N",
|
|
69
|
+
]
|
|
70
|
+
ignore = [
|
|
71
|
+
"S101",
|
|
72
|
+
"N802",
|
|
73
|
+
]
|
|
74
|
+
|
|
75
|
+
[tool.ruff.lint.per-file-ignores]
|
|
76
|
+
"tests/*" = ["S101"]
|
|
77
|
+
|
|
78
|
+
[tool.ruff.lint.isort]
|
|
79
|
+
known-first-party = ["colloquial"]
|
|
80
|
+
|
|
81
|
+
[tool.ruff.format]
|
|
82
|
+
quote-style = "double"
|
|
83
|
+
indent-style = "space"
|
|
84
|
+
|
|
85
|
+
[tool.mypy]
|
|
86
|
+
python_version = "3.10"
|
|
87
|
+
strict = true
|
|
88
|
+
show_error_codes = true
|
|
89
|
+
warn_unreachable = true
|
|
90
|
+
exclude = ["tests/"]
|
|
91
|
+
|
|
92
|
+
[tool.bandit]
|
|
93
|
+
exclude_dirs = ["tests", ".venv"]
|
|
94
|
+
skips = ["B101"]
|
|
95
|
+
|
|
96
|
+
[tool.coverage.run]
|
|
97
|
+
# Branch coverage too: an `if` whose false side nobody exercised is untested
|
|
98
|
+
# logic, and line coverage alone would call it covered.
|
|
99
|
+
branch = true
|
|
100
|
+
source = ["colloquial"]
|
|
101
|
+
|
|
102
|
+
[tool.pytest.ini_options]
|
|
103
|
+
testpaths = ["tests"]
|
|
104
|
+
addopts = [
|
|
105
|
+
"--cov=colloquial",
|
|
106
|
+
"--cov-report=term-missing",
|
|
107
|
+
"--cov-fail-under=100",
|
|
108
|
+
"-ra",
|
|
109
|
+
]
|
|
110
|
+
filterwarnings = [
|
|
111
|
+
# Running a module as __main__ after it was imported is exactly what the
|
|
112
|
+
# entrypoint tests do; runpy's warning about it is expected and harmless.
|
|
113
|
+
"ignore::RuntimeWarning:runpy",
|
|
114
|
+
]
|