glitchlings 0.10.2__cp312-cp312-macosx_11_0_universal2.whl
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.
Potentially problematic release.
This version of glitchlings might be problematic. Click here for more details.
- glitchlings/__init__.py +99 -0
- glitchlings/__main__.py +8 -0
- glitchlings/_zoo_rust/__init__.py +12 -0
- glitchlings/_zoo_rust.cpython-312-darwin.so +0 -0
- glitchlings/assets/__init__.py +180 -0
- glitchlings/assets/apostrofae_pairs.json +32 -0
- glitchlings/assets/ekkokin_homophones.json +2014 -0
- glitchlings/assets/hokey_assets.json +193 -0
- glitchlings/assets/lexemes/academic.json +1049 -0
- glitchlings/assets/lexemes/colors.json +1333 -0
- glitchlings/assets/lexemes/corporate.json +716 -0
- glitchlings/assets/lexemes/cyberpunk.json +22 -0
- glitchlings/assets/lexemes/lovecraftian.json +23 -0
- glitchlings/assets/lexemes/synonyms.json +3354 -0
- glitchlings/assets/mim1c_homoglyphs.json.gz.b64 +1064 -0
- glitchlings/assets/ocr_confusions.tsv +30 -0
- glitchlings/assets/pipeline_assets.json +29 -0
- glitchlings/attack/__init__.py +147 -0
- glitchlings/attack/analysis.py +1321 -0
- glitchlings/attack/core.py +493 -0
- glitchlings/attack/core_execution.py +367 -0
- glitchlings/attack/core_planning.py +612 -0
- glitchlings/attack/encode.py +114 -0
- glitchlings/attack/metrics.py +218 -0
- glitchlings/attack/metrics_dispatch.py +70 -0
- glitchlings/attack/tokenization.py +227 -0
- glitchlings/auggie.py +284 -0
- glitchlings/compat/__init__.py +9 -0
- glitchlings/compat/loaders.py +355 -0
- glitchlings/compat/types.py +41 -0
- glitchlings/conf/__init__.py +41 -0
- glitchlings/conf/loaders.py +331 -0
- glitchlings/conf/schema.py +156 -0
- glitchlings/conf/types.py +72 -0
- glitchlings/config.toml +2 -0
- glitchlings/constants.py +59 -0
- glitchlings/dev/__init__.py +3 -0
- glitchlings/dev/docs.py +45 -0
- glitchlings/dlc/__init__.py +19 -0
- glitchlings/dlc/_shared.py +296 -0
- glitchlings/dlc/gutenberg.py +400 -0
- glitchlings/dlc/huggingface.py +68 -0
- glitchlings/dlc/prime.py +215 -0
- glitchlings/dlc/pytorch.py +98 -0
- glitchlings/dlc/pytorch_lightning.py +173 -0
- glitchlings/internal/__init__.py +16 -0
- glitchlings/internal/rust.py +159 -0
- glitchlings/internal/rust_ffi.py +490 -0
- glitchlings/main.py +426 -0
- glitchlings/protocols.py +91 -0
- glitchlings/runtime_config.py +24 -0
- glitchlings/util/__init__.py +27 -0
- glitchlings/util/adapters.py +65 -0
- glitchlings/util/keyboards.py +356 -0
- glitchlings/util/transcripts.py +108 -0
- glitchlings/zoo/__init__.py +161 -0
- glitchlings/zoo/assets/__init__.py +29 -0
- glitchlings/zoo/core.py +678 -0
- glitchlings/zoo/core_execution.py +154 -0
- glitchlings/zoo/core_planning.py +451 -0
- glitchlings/zoo/corrupt_dispatch.py +295 -0
- glitchlings/zoo/hokey.py +139 -0
- glitchlings/zoo/jargoyle.py +243 -0
- glitchlings/zoo/mim1c.py +148 -0
- glitchlings/zoo/pedant/__init__.py +109 -0
- glitchlings/zoo/pedant/core.py +105 -0
- glitchlings/zoo/pedant/forms.py +74 -0
- glitchlings/zoo/pedant/stones.py +74 -0
- glitchlings/zoo/redactyl.py +97 -0
- glitchlings/zoo/rng.py +259 -0
- glitchlings/zoo/rushmore.py +416 -0
- glitchlings/zoo/scannequin.py +66 -0
- glitchlings/zoo/transforms.py +346 -0
- glitchlings/zoo/typogre.py +128 -0
- glitchlings/zoo/validation.py +477 -0
- glitchlings/zoo/wherewolf.py +120 -0
- glitchlings/zoo/zeedub.py +93 -0
- glitchlings-0.10.2.dist-info/METADATA +337 -0
- glitchlings-0.10.2.dist-info/RECORD +83 -0
- glitchlings-0.10.2.dist-info/WHEEL +5 -0
- glitchlings-0.10.2.dist-info/entry_points.txt +3 -0
- glitchlings-0.10.2.dist-info/licenses/LICENSE +201 -0
- glitchlings-0.10.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
"""Centralized Rust FFI operations module.
|
|
2
|
+
|
|
3
|
+
This module is the **single entry point** for all Rust FFI calls in the codebase.
|
|
4
|
+
All glitchling transformations that delegate to Rust must go through this module.
|
|
5
|
+
|
|
6
|
+
**Design Philosophy:**
|
|
7
|
+
|
|
8
|
+
This module is explicitly *impure* - it loads and invokes compiled Rust functions
|
|
9
|
+
which are stateful operations. By centralizing all FFI here:
|
|
10
|
+
|
|
11
|
+
1. Pure modules (validation.py, transforms.py, rng.py) never import Rust
|
|
12
|
+
2. The Rust dependency is explicit and traceable
|
|
13
|
+
3. Testing can mock this module to verify Python-only paths
|
|
14
|
+
4. Side effects from FFI are isolated to one location
|
|
15
|
+
|
|
16
|
+
**Usage Pattern:**
|
|
17
|
+
|
|
18
|
+
# In a glitchling module (e.g., typogre.py)
|
|
19
|
+
from glitchlings.internal.rust_ffi import fatfinger_rust
|
|
20
|
+
|
|
21
|
+
def fatfinger(text: str, rate: float, ...) -> str:
|
|
22
|
+
# ... validation and setup ...
|
|
23
|
+
return fatfinger_rust(text, rate, layout, seed)
|
|
24
|
+
|
|
25
|
+
See AGENTS.md "Functional Purity Architecture" for full details.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
from __future__ import annotations
|
|
29
|
+
|
|
30
|
+
from typing import Any, Literal, Mapping, Sequence, cast
|
|
31
|
+
|
|
32
|
+
from .rust import get_rust_operation, load_rust_module, resolve_seed
|
|
33
|
+
|
|
34
|
+
# Re-export resolve_seed for backward compatibility
|
|
35
|
+
__all__ = [
|
|
36
|
+
# Seed resolution (re-exported from rust.py)
|
|
37
|
+
"resolve_seed",
|
|
38
|
+
# Orchestration operations
|
|
39
|
+
"plan_glitchlings_rust",
|
|
40
|
+
"compose_glitchlings_rust",
|
|
41
|
+
"build_pipeline_rust",
|
|
42
|
+
"RustPipeline",
|
|
43
|
+
# Character-level operations
|
|
44
|
+
"fatfinger_rust",
|
|
45
|
+
"slip_modifier_rust",
|
|
46
|
+
"mim1c_rust",
|
|
47
|
+
"ocr_artifacts_rust",
|
|
48
|
+
"inject_zero_widths_rust",
|
|
49
|
+
"hokey_rust",
|
|
50
|
+
# Word-level operations
|
|
51
|
+
"delete_random_words_rust",
|
|
52
|
+
"reduplicate_words_rust",
|
|
53
|
+
"swap_adjacent_words_rust",
|
|
54
|
+
"redact_words_rust",
|
|
55
|
+
"jargoyle_drift_rust",
|
|
56
|
+
"list_lexeme_dictionaries_rust",
|
|
57
|
+
"wherewolf_homophones_rust",
|
|
58
|
+
# Grammar operations
|
|
59
|
+
"pedant_rust",
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
# ---------------------------------------------------------------------------
|
|
64
|
+
# Type Aliases
|
|
65
|
+
# ---------------------------------------------------------------------------
|
|
66
|
+
|
|
67
|
+
# Orchestration types
|
|
68
|
+
PlanResult = list[tuple[int, int]]
|
|
69
|
+
PipelineDescriptor = Mapping[str, Any]
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
# ---------------------------------------------------------------------------
|
|
73
|
+
# Pipeline wrapper
|
|
74
|
+
# ---------------------------------------------------------------------------
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class RustPipeline:
|
|
78
|
+
"""Thin wrapper around the compiled Rust Pipeline class."""
|
|
79
|
+
|
|
80
|
+
def __init__(
|
|
81
|
+
self,
|
|
82
|
+
descriptors: Sequence[PipelineDescriptor],
|
|
83
|
+
master_seed: int,
|
|
84
|
+
*,
|
|
85
|
+
include_only_patterns: Sequence[str] | None = None,
|
|
86
|
+
exclude_patterns: Sequence[str] | None = None,
|
|
87
|
+
) -> None:
|
|
88
|
+
module = load_rust_module()
|
|
89
|
+
pipeline_cls = getattr(module, "Pipeline")
|
|
90
|
+
include_patterns_list = (
|
|
91
|
+
list(include_only_patterns) if include_only_patterns is not None else None
|
|
92
|
+
)
|
|
93
|
+
exclude_patterns_list = list(exclude_patterns) if exclude_patterns is not None else None
|
|
94
|
+
self._pipeline = pipeline_cls(
|
|
95
|
+
list(descriptors), int(master_seed), include_patterns_list, exclude_patterns_list
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
def run(self, text: str) -> str:
|
|
99
|
+
return cast(str, self._pipeline.run(text))
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
# ---------------------------------------------------------------------------
|
|
103
|
+
# Orchestration Operations
|
|
104
|
+
# ---------------------------------------------------------------------------
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def plan_glitchlings_rust(
|
|
108
|
+
specs: Sequence[Mapping[str, Any]],
|
|
109
|
+
master_seed: int,
|
|
110
|
+
) -> PlanResult:
|
|
111
|
+
"""Invoke Rust orchestration planner.
|
|
112
|
+
|
|
113
|
+
Args:
|
|
114
|
+
specs: Sequence of glitchling specifications with name/scope/order.
|
|
115
|
+
master_seed: Master seed for deterministic ordering.
|
|
116
|
+
|
|
117
|
+
Returns:
|
|
118
|
+
List of (index, derived_seed) tuples defining execution order.
|
|
119
|
+
"""
|
|
120
|
+
plan_fn = get_rust_operation("plan_glitchlings")
|
|
121
|
+
plan = plan_fn(specs, int(master_seed))
|
|
122
|
+
return [(int(index), int(seed)) for index, seed in plan]
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def compose_glitchlings_rust(
|
|
126
|
+
text: str,
|
|
127
|
+
descriptors: Sequence[PipelineDescriptor],
|
|
128
|
+
master_seed: int,
|
|
129
|
+
*,
|
|
130
|
+
include_only_patterns: Sequence[str] | None = None,
|
|
131
|
+
exclude_patterns: Sequence[str] | None = None,
|
|
132
|
+
) -> str:
|
|
133
|
+
"""Execute a sequence of glitchlings through the Rust pipeline.
|
|
134
|
+
|
|
135
|
+
Args:
|
|
136
|
+
text: Input text to transform.
|
|
137
|
+
descriptors: Pipeline descriptors for each glitchling.
|
|
138
|
+
master_seed: Master seed for determinism.
|
|
139
|
+
include_only_patterns: Regex patterns limiting mutations to matching spans.
|
|
140
|
+
exclude_patterns: Regex patterns that should not be modified.
|
|
141
|
+
|
|
142
|
+
Returns:
|
|
143
|
+
Transformed text.
|
|
144
|
+
"""
|
|
145
|
+
pipeline = RustPipeline(
|
|
146
|
+
descriptors,
|
|
147
|
+
int(master_seed),
|
|
148
|
+
include_only_patterns=include_only_patterns,
|
|
149
|
+
exclude_patterns=exclude_patterns,
|
|
150
|
+
)
|
|
151
|
+
return pipeline.run(text)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def build_pipeline_rust(
|
|
155
|
+
descriptors: Sequence[PipelineDescriptor],
|
|
156
|
+
master_seed: int,
|
|
157
|
+
*,
|
|
158
|
+
include_only_patterns: Sequence[str] | None = None,
|
|
159
|
+
exclude_patterns: Sequence[str] | None = None,
|
|
160
|
+
) -> RustPipeline:
|
|
161
|
+
"""Instantiate a Rust pipeline for reuse across calls."""
|
|
162
|
+
return RustPipeline(
|
|
163
|
+
descriptors,
|
|
164
|
+
master_seed,
|
|
165
|
+
include_only_patterns=include_only_patterns,
|
|
166
|
+
exclude_patterns=exclude_patterns,
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
# ---------------------------------------------------------------------------
|
|
171
|
+
# Character-Level Operations
|
|
172
|
+
# ---------------------------------------------------------------------------
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def fatfinger_rust(
|
|
176
|
+
text: str,
|
|
177
|
+
rate: float,
|
|
178
|
+
layout: Mapping[str, Sequence[str]],
|
|
179
|
+
seed: int,
|
|
180
|
+
*,
|
|
181
|
+
shift_slip_rate: float | None = None,
|
|
182
|
+
shift_slip_exit_rate: float | None = None,
|
|
183
|
+
shift_map: Mapping[str, str] | None = None,
|
|
184
|
+
) -> str:
|
|
185
|
+
"""Introduce keyboard typos via Rust.
|
|
186
|
+
|
|
187
|
+
Args:
|
|
188
|
+
text: Input text.
|
|
189
|
+
rate: Probability of corrupting each character.
|
|
190
|
+
layout: Keyboard neighbor mapping.
|
|
191
|
+
seed: Deterministic seed.
|
|
192
|
+
shift_slip_rate: Probability of entering a shifted burst before fat-fingering.
|
|
193
|
+
shift_slip_exit_rate: Probability of releasing shift during a burst.
|
|
194
|
+
shift_map: Mapping of unshifted -> shifted keys for the active layout.
|
|
195
|
+
|
|
196
|
+
Returns:
|
|
197
|
+
Text with simulated typing errors.
|
|
198
|
+
"""
|
|
199
|
+
fn = get_rust_operation("fatfinger")
|
|
200
|
+
return cast(
|
|
201
|
+
str,
|
|
202
|
+
fn(text, rate, layout, seed, shift_slip_rate, shift_slip_exit_rate, shift_map),
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def slip_modifier_rust(
|
|
207
|
+
text: str,
|
|
208
|
+
enter_rate: float,
|
|
209
|
+
exit_rate: float,
|
|
210
|
+
shift_map: Mapping[str, str],
|
|
211
|
+
seed: int | None,
|
|
212
|
+
) -> str:
|
|
213
|
+
"""Apply a modifier slippage burst using Rust.
|
|
214
|
+
|
|
215
|
+
Args:
|
|
216
|
+
text: Input text.
|
|
217
|
+
enter_rate: Probability of starting a shift burst.
|
|
218
|
+
exit_rate: Probability of ending a burst once started.
|
|
219
|
+
shift_map: Mapping of unshifted -> shifted characters.
|
|
220
|
+
seed: Deterministic seed.
|
|
221
|
+
|
|
222
|
+
Returns:
|
|
223
|
+
Text with modifier slippage applied.
|
|
224
|
+
"""
|
|
225
|
+
fn = get_rust_operation("slip_modifier")
|
|
226
|
+
return cast(str, fn(text, enter_rate, exit_rate, shift_map, seed))
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def mim1c_rust(
|
|
230
|
+
text: str,
|
|
231
|
+
rate: float,
|
|
232
|
+
classes: list[str] | Literal["all"] | None,
|
|
233
|
+
banned: list[str] | None,
|
|
234
|
+
seed: int,
|
|
235
|
+
) -> str:
|
|
236
|
+
"""Replace characters with homoglyphs via Rust.
|
|
237
|
+
|
|
238
|
+
Args:
|
|
239
|
+
text: Input text.
|
|
240
|
+
rate: Probability of swapping each character.
|
|
241
|
+
classes: Homoglyph classes to use, or "all".
|
|
242
|
+
banned: Characters to never replace with.
|
|
243
|
+
seed: Deterministic seed.
|
|
244
|
+
|
|
245
|
+
Returns:
|
|
246
|
+
Text with homoglyph substitutions.
|
|
247
|
+
"""
|
|
248
|
+
fn = get_rust_operation("mim1c")
|
|
249
|
+
return cast(str, fn(text, rate, classes, banned, seed))
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def ocr_artifacts_rust(
|
|
253
|
+
text: str,
|
|
254
|
+
rate: float,
|
|
255
|
+
seed: int,
|
|
256
|
+
) -> str:
|
|
257
|
+
"""Introduce OCR-like artifacts via Rust.
|
|
258
|
+
|
|
259
|
+
Args:
|
|
260
|
+
text: Input text.
|
|
261
|
+
rate: Probability of introducing artifacts.
|
|
262
|
+
seed: Deterministic seed.
|
|
263
|
+
|
|
264
|
+
Returns:
|
|
265
|
+
Text with simulated OCR errors.
|
|
266
|
+
"""
|
|
267
|
+
fn = get_rust_operation("ocr_artifacts")
|
|
268
|
+
return cast(str, fn(text, rate, seed))
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
def inject_zero_widths_rust(
|
|
272
|
+
text: str,
|
|
273
|
+
rate: float,
|
|
274
|
+
characters: list[str],
|
|
275
|
+
seed: int | None,
|
|
276
|
+
) -> str:
|
|
277
|
+
"""Inject zero-width characters via Rust.
|
|
278
|
+
|
|
279
|
+
Args:
|
|
280
|
+
text: Input text.
|
|
281
|
+
rate: Probability of injection between characters.
|
|
282
|
+
characters: Palette of zero-width characters to use.
|
|
283
|
+
seed: Deterministic seed.
|
|
284
|
+
|
|
285
|
+
Returns:
|
|
286
|
+
Text with injected zero-width characters.
|
|
287
|
+
"""
|
|
288
|
+
fn = get_rust_operation("inject_zero_widths")
|
|
289
|
+
return cast(str, fn(text, rate, characters, seed))
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def hokey_rust(
|
|
293
|
+
text: str,
|
|
294
|
+
rate: float,
|
|
295
|
+
extension_min: int,
|
|
296
|
+
extension_max: int,
|
|
297
|
+
word_length_threshold: int,
|
|
298
|
+
base_p: float,
|
|
299
|
+
seed: int | None,
|
|
300
|
+
) -> str:
|
|
301
|
+
"""Extend expressive segments via Rust.
|
|
302
|
+
|
|
303
|
+
Args:
|
|
304
|
+
text: Input text.
|
|
305
|
+
rate: Selection rate for candidate words.
|
|
306
|
+
extension_min: Minimum extra repetitions.
|
|
307
|
+
extension_max: Maximum extra repetitions.
|
|
308
|
+
word_length_threshold: Preferred max word length.
|
|
309
|
+
base_p: Base probability for sampler.
|
|
310
|
+
seed: Deterministic seed.
|
|
311
|
+
|
|
312
|
+
Returns:
|
|
313
|
+
Text with extended expressive segments.
|
|
314
|
+
"""
|
|
315
|
+
fn = get_rust_operation("hokey")
|
|
316
|
+
return cast(
|
|
317
|
+
str,
|
|
318
|
+
fn(text, rate, extension_min, extension_max, word_length_threshold, base_p, seed),
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
# ---------------------------------------------------------------------------
|
|
323
|
+
# Word-Level Operations
|
|
324
|
+
# ---------------------------------------------------------------------------
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
def delete_random_words_rust(
|
|
328
|
+
text: str,
|
|
329
|
+
rate: float,
|
|
330
|
+
unweighted: bool,
|
|
331
|
+
seed: int,
|
|
332
|
+
) -> str:
|
|
333
|
+
"""Delete random words via Rust.
|
|
334
|
+
|
|
335
|
+
Args:
|
|
336
|
+
text: Input text.
|
|
337
|
+
rate: Probability of deleting each word.
|
|
338
|
+
unweighted: If True, use uniform selection; else weight by length.
|
|
339
|
+
seed: Deterministic seed.
|
|
340
|
+
|
|
341
|
+
Returns:
|
|
342
|
+
Text with words deleted.
|
|
343
|
+
"""
|
|
344
|
+
fn = get_rust_operation("delete_random_words")
|
|
345
|
+
return cast(str, fn(text, rate, unweighted, seed))
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
def reduplicate_words_rust(
|
|
349
|
+
text: str,
|
|
350
|
+
rate: float,
|
|
351
|
+
unweighted: bool,
|
|
352
|
+
seed: int,
|
|
353
|
+
) -> str:
|
|
354
|
+
"""Reduplicate random words via Rust.
|
|
355
|
+
|
|
356
|
+
Args:
|
|
357
|
+
text: Input text.
|
|
358
|
+
rate: Probability of duplicating each word.
|
|
359
|
+
unweighted: If True, use uniform selection; else weight by length.
|
|
360
|
+
seed: Deterministic seed.
|
|
361
|
+
|
|
362
|
+
Returns:
|
|
363
|
+
Text with words duplicated.
|
|
364
|
+
"""
|
|
365
|
+
fn = get_rust_operation("reduplicate_words")
|
|
366
|
+
return cast(str, fn(text, rate, unweighted, seed))
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
def swap_adjacent_words_rust(
|
|
370
|
+
text: str,
|
|
371
|
+
rate: float,
|
|
372
|
+
seed: int,
|
|
373
|
+
) -> str:
|
|
374
|
+
"""Swap adjacent words via Rust.
|
|
375
|
+
|
|
376
|
+
Args:
|
|
377
|
+
text: Input text.
|
|
378
|
+
rate: Probability of swapping adjacent word pairs.
|
|
379
|
+
seed: Deterministic seed.
|
|
380
|
+
|
|
381
|
+
Returns:
|
|
382
|
+
Text with adjacent words swapped.
|
|
383
|
+
"""
|
|
384
|
+
fn = get_rust_operation("swap_adjacent_words")
|
|
385
|
+
return cast(str, fn(text, rate, seed))
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
def redact_words_rust(
|
|
389
|
+
text: str,
|
|
390
|
+
replacement: str,
|
|
391
|
+
rate: float,
|
|
392
|
+
merge: bool,
|
|
393
|
+
unweighted: bool,
|
|
394
|
+
seed: int,
|
|
395
|
+
) -> str:
|
|
396
|
+
"""Redact random words via Rust.
|
|
397
|
+
|
|
398
|
+
Args:
|
|
399
|
+
text: Input text.
|
|
400
|
+
replacement: Character to replace word characters with.
|
|
401
|
+
rate: Probability of redacting each word.
|
|
402
|
+
merge: If True, merge adjacent redactions.
|
|
403
|
+
unweighted: If True, use uniform selection; else weight by length.
|
|
404
|
+
seed: Deterministic seed.
|
|
405
|
+
|
|
406
|
+
Returns:
|
|
407
|
+
Text with words redacted.
|
|
408
|
+
"""
|
|
409
|
+
fn = get_rust_operation("redact_words")
|
|
410
|
+
return cast(str, fn(text, replacement, rate, merge, unweighted, seed))
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
def jargoyle_drift_rust(
|
|
414
|
+
text: str,
|
|
415
|
+
lexemes: str,
|
|
416
|
+
mode: str,
|
|
417
|
+
rate: float,
|
|
418
|
+
seed: int | None,
|
|
419
|
+
) -> str:
|
|
420
|
+
"""Apply Jargoyle dictionary-based word drift via Rust.
|
|
421
|
+
|
|
422
|
+
Args:
|
|
423
|
+
text: Input text.
|
|
424
|
+
lexemes: Name of the dictionary to use (colors, synonyms, corporate, academic, cyberpunk,
|
|
425
|
+
lovecraftian, or any custom dictionary discovered in the lexemes directory).
|
|
426
|
+
mode: Drift mode ("literal" or "drift").
|
|
427
|
+
rate: Probability of transforming each matching word.
|
|
428
|
+
seed: Deterministic seed (only used for "drift" mode).
|
|
429
|
+
|
|
430
|
+
Returns:
|
|
431
|
+
Text with word substitutions applied.
|
|
432
|
+
"""
|
|
433
|
+
fn = get_rust_operation("jargoyle_drift")
|
|
434
|
+
return cast(str, fn(text, lexemes, mode, rate, seed))
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
def list_lexeme_dictionaries_rust() -> list[str]:
|
|
438
|
+
"""List available lexeme dictionaries.
|
|
439
|
+
|
|
440
|
+
Returns:
|
|
441
|
+
List of dictionary names available for Jargoyle.
|
|
442
|
+
"""
|
|
443
|
+
fn = get_rust_operation("list_lexeme_dictionaries")
|
|
444
|
+
return cast(list[str], fn())
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
def wherewolf_homophones_rust(
|
|
448
|
+
text: str,
|
|
449
|
+
rate: float,
|
|
450
|
+
weighting: str,
|
|
451
|
+
seed: int | None,
|
|
452
|
+
) -> str:
|
|
453
|
+
"""Substitute words with homophones via Rust.
|
|
454
|
+
|
|
455
|
+
Args:
|
|
456
|
+
text: Input text.
|
|
457
|
+
rate: Probability of substituting each word.
|
|
458
|
+
weighting: Weighting mode for selection.
|
|
459
|
+
seed: Deterministic seed.
|
|
460
|
+
|
|
461
|
+
Returns:
|
|
462
|
+
Text with homophone substitutions.
|
|
463
|
+
"""
|
|
464
|
+
fn = get_rust_operation("wherewolf_homophones")
|
|
465
|
+
return cast(str, fn(text, rate, weighting, seed))
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
# ---------------------------------------------------------------------------
|
|
469
|
+
# Grammar Operations
|
|
470
|
+
# ---------------------------------------------------------------------------
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
def pedant_rust(
|
|
474
|
+
text: str,
|
|
475
|
+
*,
|
|
476
|
+
stone: str,
|
|
477
|
+
seed: int,
|
|
478
|
+
) -> str:
|
|
479
|
+
"""Apply pedant grammar transformation via Rust.
|
|
480
|
+
|
|
481
|
+
Args:
|
|
482
|
+
text: Input text.
|
|
483
|
+
stone: Pedant stone label defining transformation type.
|
|
484
|
+
seed: Deterministic seed.
|
|
485
|
+
|
|
486
|
+
Returns:
|
|
487
|
+
Text with grammar transformation applied.
|
|
488
|
+
"""
|
|
489
|
+
fn = get_rust_operation("pedant")
|
|
490
|
+
return cast(str, fn(text, stone=stone, seed=seed))
|