kiwi-code 0.0.29__tar.gz → 0.0.30__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.
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/PKG-INFO +1 -1
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/pyproject.toml +1 -1
- kiwi_code-0.0.30/src/kiwi_tui/random_words.py +9 -0
- kiwi_code-0.0.30/src/kiwi_tui/status_words.py +481 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/uv.lock +1 -1
- kiwi_code-0.0.29/src/kiwi_tui/random_words.py +0 -80
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/.github/workflows/publish.yml +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/.github/workflows/test.yml +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/.gitignore +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/.python-version +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/CLAUDE.md +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/Makefile +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/README.md +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_cli/__init__.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_cli/auth.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_cli/cli.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_cli/client.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_cli/commands.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_cli/logger.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_cli/models.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_cli/runtime_manager.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_cli/server.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_runtime/__init__.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_runtime/__main__.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_runtime/main.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_runtime/snake_game/.gitignore +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_runtime/snake_game/requirements.txt +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_tui/__init__.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_tui/inline_file_picker.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_tui/main.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_tui/runtime_agent.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_tui/screens/__init__.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_tui/screens/attach_content.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_tui/screens/command_result.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_tui/screens/dashboard.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_tui/screens/file_browser.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_tui/screens/help.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_tui/screens/id_picker.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_tui/screens/login.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_tui/screens/runtime_cleanup.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_tui/screens/runtime_logs.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_tui/screens/slash_picker.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_tui/slash_commands.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/src/kiwi_tui/widgets.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/test_hello.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/tests/__init__.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/tests/conftest.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/tests/test_cli_help.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/tests/test_imports.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/tests/test_reexec_kiwi.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/tests/test_runtime_log_trimming.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/tests/test_tokens.py +0 -0
- {kiwi_code-0.0.29 → kiwi_code-0.0.30}/tests/test_tui_headless.py +0 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
from kiwi_tui.status_words import next_status_word
|
|
2
|
+
def random_verb(*, default: str = "Thinking") -> str:
|
|
3
|
+
"""Return a curated "-ing" status word for display (e.g. "Searching")."""
|
|
4
|
+
|
|
5
|
+
return next_status_word(default=default)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def random_adjective(*, default: str = "Curious") -> str: # pragma: no cover
|
|
9
|
+
return default
|
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
from collections import deque
|
|
2
|
+
from dataclasses import dataclass, field
|
|
3
|
+
from functools import lru_cache
|
|
4
|
+
import random
|
|
5
|
+
import threading
|
|
6
|
+
import time
|
|
7
|
+
from typing import Deque, Iterable
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
_STATUS_WORDS_RAW: tuple[str, ...] = (
|
|
11
|
+
"Thinking",
|
|
12
|
+
"Working",
|
|
13
|
+
"Responding",
|
|
14
|
+
"Reasoning",
|
|
15
|
+
"Reflecting",
|
|
16
|
+
"Considering",
|
|
17
|
+
"Pondering",
|
|
18
|
+
"Deliberating",
|
|
19
|
+
"Planning",
|
|
20
|
+
"Prioritizing",
|
|
21
|
+
"Organizing",
|
|
22
|
+
"Outlining",
|
|
23
|
+
"Strategizing",
|
|
24
|
+
"Brainstorming",
|
|
25
|
+
"Ideating",
|
|
26
|
+
"Envisioning",
|
|
27
|
+
"Imagining",
|
|
28
|
+
"Inferring",
|
|
29
|
+
"Deducing",
|
|
30
|
+
"Concluding",
|
|
31
|
+
"Deciding",
|
|
32
|
+
"Choosing",
|
|
33
|
+
"Reconsidering",
|
|
34
|
+
"Reassessing",
|
|
35
|
+
"Evaluating",
|
|
36
|
+
"Estimating",
|
|
37
|
+
"Calculating",
|
|
38
|
+
"Computing",
|
|
39
|
+
"Measuring",
|
|
40
|
+
"Counting",
|
|
41
|
+
"Timing",
|
|
42
|
+
"Comparing",
|
|
43
|
+
"Contrasting",
|
|
44
|
+
"Weighing",
|
|
45
|
+
"Balancing",
|
|
46
|
+
"Aligning",
|
|
47
|
+
"Centering",
|
|
48
|
+
"Spacing",
|
|
49
|
+
"Arranging",
|
|
50
|
+
"Resizing",
|
|
51
|
+
"Wrapping",
|
|
52
|
+
"Rendering",
|
|
53
|
+
"Styling",
|
|
54
|
+
"Theming",
|
|
55
|
+
"Polishing",
|
|
56
|
+
"Refining",
|
|
57
|
+
"Improving",
|
|
58
|
+
"Optimizing",
|
|
59
|
+
"Tuning",
|
|
60
|
+
"Simplifying",
|
|
61
|
+
"Streamlining",
|
|
62
|
+
"Modernizing",
|
|
63
|
+
"Upgrading",
|
|
64
|
+
"Updating",
|
|
65
|
+
"Reworking",
|
|
66
|
+
"Rewriting",
|
|
67
|
+
"Editing",
|
|
68
|
+
"Proofreading",
|
|
69
|
+
"Formatting",
|
|
70
|
+
"Drafting",
|
|
71
|
+
"Writing",
|
|
72
|
+
"Summarizing",
|
|
73
|
+
"Condensing",
|
|
74
|
+
"Clarifying",
|
|
75
|
+
"Explaining",
|
|
76
|
+
"Describing",
|
|
77
|
+
"Documenting",
|
|
78
|
+
"Annotating",
|
|
79
|
+
"Commenting",
|
|
80
|
+
"Noting",
|
|
81
|
+
"Labeling",
|
|
82
|
+
"Tagging",
|
|
83
|
+
"Indexing",
|
|
84
|
+
"Cataloging",
|
|
85
|
+
"Listing",
|
|
86
|
+
"Sorting",
|
|
87
|
+
"Grouping",
|
|
88
|
+
"Filtering",
|
|
89
|
+
"Selecting",
|
|
90
|
+
"Collecting",
|
|
91
|
+
"Gathering",
|
|
92
|
+
"Compiling",
|
|
93
|
+
"Assembling",
|
|
94
|
+
"Combining",
|
|
95
|
+
"Merging",
|
|
96
|
+
"Splitting",
|
|
97
|
+
"Separating",
|
|
98
|
+
"Isolating",
|
|
99
|
+
"Narrowing",
|
|
100
|
+
"Pinpointing",
|
|
101
|
+
"Investigating",
|
|
102
|
+
"Inspecting",
|
|
103
|
+
"Reviewing",
|
|
104
|
+
"Rereading",
|
|
105
|
+
"Reading",
|
|
106
|
+
"Scanning",
|
|
107
|
+
"Browsing",
|
|
108
|
+
"Searching",
|
|
109
|
+
"Exploring",
|
|
110
|
+
"Discovering",
|
|
111
|
+
"Observing",
|
|
112
|
+
"Monitoring",
|
|
113
|
+
"Tracking",
|
|
114
|
+
"Tracing",
|
|
115
|
+
"Logging",
|
|
116
|
+
"Instrumenting",
|
|
117
|
+
"Profiling",
|
|
118
|
+
"Benchmarking",
|
|
119
|
+
"Testing",
|
|
120
|
+
"Retesting",
|
|
121
|
+
"Validating",
|
|
122
|
+
"Verifying",
|
|
123
|
+
"Confirming",
|
|
124
|
+
"Checking",
|
|
125
|
+
"Crosschecking",
|
|
126
|
+
"Doublechecking",
|
|
127
|
+
"Rechecking",
|
|
128
|
+
"Auditing",
|
|
129
|
+
"Diagnosing",
|
|
130
|
+
"Debugging",
|
|
131
|
+
"Reproducing",
|
|
132
|
+
"Triaging",
|
|
133
|
+
"Resolving",
|
|
134
|
+
"Fixing",
|
|
135
|
+
"Repairing",
|
|
136
|
+
"Mitigating",
|
|
137
|
+
"Preventing",
|
|
138
|
+
"Safeguarding",
|
|
139
|
+
"Securing",
|
|
140
|
+
"Hardening",
|
|
141
|
+
"Sanitizing",
|
|
142
|
+
"Normalizing",
|
|
143
|
+
"Cleaning",
|
|
144
|
+
"Tidying",
|
|
145
|
+
"Pruning",
|
|
146
|
+
"Trimming",
|
|
147
|
+
"Archiving",
|
|
148
|
+
"Restoring",
|
|
149
|
+
"Saving",
|
|
150
|
+
"Autosaving",
|
|
151
|
+
"Persisting",
|
|
152
|
+
"Storing",
|
|
153
|
+
"Caching",
|
|
154
|
+
"Preloading",
|
|
155
|
+
"Loading",
|
|
156
|
+
"Fetching",
|
|
157
|
+
"Retrieving",
|
|
158
|
+
"Downloading",
|
|
159
|
+
"Uploading",
|
|
160
|
+
"Syncing",
|
|
161
|
+
"Synchronizing",
|
|
162
|
+
"Refreshing",
|
|
163
|
+
"Connecting",
|
|
164
|
+
"Reconnecting",
|
|
165
|
+
"Handshaking",
|
|
166
|
+
"Authenticating",
|
|
167
|
+
"Authorizing",
|
|
168
|
+
"Negotiating",
|
|
169
|
+
"Provisioning",
|
|
170
|
+
"Initializing",
|
|
171
|
+
"Booting",
|
|
172
|
+
"Starting",
|
|
173
|
+
"Restarting",
|
|
174
|
+
"Resuming",
|
|
175
|
+
"Pausing",
|
|
176
|
+
"Waiting",
|
|
177
|
+
"Queueing",
|
|
178
|
+
"Retrying",
|
|
179
|
+
"Recovering",
|
|
180
|
+
"Stabilizing",
|
|
181
|
+
"Configuring",
|
|
182
|
+
"Reconfiguring",
|
|
183
|
+
"Customizing",
|
|
184
|
+
"Parameterizing",
|
|
185
|
+
"Templating",
|
|
186
|
+
"Generating",
|
|
187
|
+
"Synthesizing",
|
|
188
|
+
"Deriving",
|
|
189
|
+
"Transforming",
|
|
190
|
+
"Parsing",
|
|
191
|
+
"Tokenizing",
|
|
192
|
+
"Serializing",
|
|
193
|
+
"Deserializing",
|
|
194
|
+
"Encoding",
|
|
195
|
+
"Decoding",
|
|
196
|
+
"Compressing",
|
|
197
|
+
"Decompressing",
|
|
198
|
+
"Encrypting",
|
|
199
|
+
"Decrypting",
|
|
200
|
+
"Migrating",
|
|
201
|
+
"Seeding",
|
|
202
|
+
"Backfilling",
|
|
203
|
+
"Importing",
|
|
204
|
+
"Exporting",
|
|
205
|
+
"Consolidating",
|
|
206
|
+
"Aggregating",
|
|
207
|
+
"Reconciling",
|
|
208
|
+
"Harmonizing",
|
|
209
|
+
"Coordinating",
|
|
210
|
+
"Collaborating",
|
|
211
|
+
"Communicating",
|
|
212
|
+
"Listening",
|
|
213
|
+
"Asking",
|
|
214
|
+
"Answering",
|
|
215
|
+
"Advising",
|
|
216
|
+
"Suggesting",
|
|
217
|
+
"Recommending",
|
|
218
|
+
"Guiding",
|
|
219
|
+
"Coaching",
|
|
220
|
+
"Helping",
|
|
221
|
+
"Assisting",
|
|
222
|
+
"Supporting",
|
|
223
|
+
"Sharing",
|
|
224
|
+
"Notifying",
|
|
225
|
+
"Reporting",
|
|
226
|
+
"Presenting",
|
|
227
|
+
"Approving",
|
|
228
|
+
"Finalizing",
|
|
229
|
+
"Launching",
|
|
230
|
+
"Deploying",
|
|
231
|
+
"Building",
|
|
232
|
+
"Bundling",
|
|
233
|
+
"Packaging",
|
|
234
|
+
"Releasing",
|
|
235
|
+
"Shipping",
|
|
236
|
+
"Installing",
|
|
237
|
+
"Uninstalling",
|
|
238
|
+
"Executing",
|
|
239
|
+
"Running",
|
|
240
|
+
"Scheduling",
|
|
241
|
+
"Orchestrating",
|
|
242
|
+
"Automating",
|
|
243
|
+
"Scripting",
|
|
244
|
+
"Branching",
|
|
245
|
+
"Committing",
|
|
246
|
+
"Rebasing",
|
|
247
|
+
"Pushing",
|
|
248
|
+
"Pulling",
|
|
249
|
+
"Cloning",
|
|
250
|
+
"Forking",
|
|
251
|
+
"Versioning",
|
|
252
|
+
"Linting",
|
|
253
|
+
"Refactoring",
|
|
254
|
+
"Modularizing",
|
|
255
|
+
"Encapsulating",
|
|
256
|
+
"Integrating",
|
|
257
|
+
"Interfacing",
|
|
258
|
+
"Adapting",
|
|
259
|
+
"Abstracting",
|
|
260
|
+
"Decomposing",
|
|
261
|
+
"Recomposing",
|
|
262
|
+
"Prototyping",
|
|
263
|
+
"Sketching",
|
|
264
|
+
"Tinkering",
|
|
265
|
+
"Noodling",
|
|
266
|
+
"Spelunking",
|
|
267
|
+
"Diagramming",
|
|
268
|
+
"Visualizing",
|
|
269
|
+
"Simulating",
|
|
270
|
+
"Emulating",
|
|
271
|
+
"Staging",
|
|
272
|
+
"Navigating",
|
|
273
|
+
"Traversing",
|
|
274
|
+
"Examining",
|
|
275
|
+
"Disambiguating",
|
|
276
|
+
"Canonicalizing",
|
|
277
|
+
"Contextualizing",
|
|
278
|
+
"Operationalizing",
|
|
279
|
+
"Instrumenting",
|
|
280
|
+
"Triangulating",
|
|
281
|
+
"Deobfuscating",
|
|
282
|
+
"Deinterleaving",
|
|
283
|
+
"Reparameterizing",
|
|
284
|
+
"Recontextualizing",
|
|
285
|
+
"Disentangling",
|
|
286
|
+
"Deconvoluting",
|
|
287
|
+
"Corroborating",
|
|
288
|
+
"Extrapolating",
|
|
289
|
+
"Interpolating",
|
|
290
|
+
"Reconceptualizing",
|
|
291
|
+
"Rationalizing",
|
|
292
|
+
"Formalizing",
|
|
293
|
+
"Generalizing",
|
|
294
|
+
"Specializing",
|
|
295
|
+
"Particularizing",
|
|
296
|
+
"Virtualizing",
|
|
297
|
+
"Containerizing",
|
|
298
|
+
"Deprovisioning",
|
|
299
|
+
"Sandboxing",
|
|
300
|
+
"Backporting",
|
|
301
|
+
"Forwardporting",
|
|
302
|
+
"Snapshotting",
|
|
303
|
+
"Diffing",
|
|
304
|
+
"Grepping",
|
|
305
|
+
"Vendoring",
|
|
306
|
+
"Reindexing",
|
|
307
|
+
"Rerendering",
|
|
308
|
+
"Revalidating",
|
|
309
|
+
"Recalibrating",
|
|
310
|
+
"Reassociating",
|
|
311
|
+
"Enumerating",
|
|
312
|
+
"Assimilating",
|
|
313
|
+
"Ameliorating",
|
|
314
|
+
"Interrogating",
|
|
315
|
+
"Disseminating",
|
|
316
|
+
"Discretizing",
|
|
317
|
+
"Denormalizing",
|
|
318
|
+
"Deprioritizing",
|
|
319
|
+
"Underprovisioning",
|
|
320
|
+
"Assimilating",
|
|
321
|
+
"Scaffolding",
|
|
322
|
+
"Excavating",
|
|
323
|
+
"Unearthing",
|
|
324
|
+
"Deciphering",
|
|
325
|
+
"Synthesizing",
|
|
326
|
+
"Converging",
|
|
327
|
+
"Diverging",
|
|
328
|
+
"Reticulating",
|
|
329
|
+
"Transpiling",
|
|
330
|
+
"Hydrating",
|
|
331
|
+
"Materializing",
|
|
332
|
+
"Manifesting",
|
|
333
|
+
"Crystallizing",
|
|
334
|
+
"Coalescing",
|
|
335
|
+
"Distilling",
|
|
336
|
+
"Ferreting",
|
|
337
|
+
"Foraging",
|
|
338
|
+
"Sifting",
|
|
339
|
+
"Winnowing",
|
|
340
|
+
"Untangling",
|
|
341
|
+
"Unraveling",
|
|
342
|
+
"Threading",
|
|
343
|
+
"Stitching",
|
|
344
|
+
"Splicing",
|
|
345
|
+
"Grafting",
|
|
346
|
+
"Weaving",
|
|
347
|
+
"Braiding",
|
|
348
|
+
"Layering",
|
|
349
|
+
"Etching",
|
|
350
|
+
"Carving",
|
|
351
|
+
"Chiseling",
|
|
352
|
+
"Sculpting",
|
|
353
|
+
"Forging",
|
|
354
|
+
"Tempering",
|
|
355
|
+
"Annealing",
|
|
356
|
+
"Calibrating",
|
|
357
|
+
"Synchronizing",
|
|
358
|
+
"Sequencing",
|
|
359
|
+
"Interleaving",
|
|
360
|
+
"Compacting",
|
|
361
|
+
"Densifying",
|
|
362
|
+
"Canonicalizing",
|
|
363
|
+
"Curating",
|
|
364
|
+
"Shepherding",
|
|
365
|
+
"Marshalling",
|
|
366
|
+
"Funneling",
|
|
367
|
+
"Grounding",
|
|
368
|
+
"Anchoring",
|
|
369
|
+
"Illuminating",
|
|
370
|
+
"Conjuring",
|
|
371
|
+
"Juggling",
|
|
372
|
+
"Wrangling",
|
|
373
|
+
"Untangling",
|
|
374
|
+
"Unsnarling",
|
|
375
|
+
"Puzzling",
|
|
376
|
+
"Scheming",
|
|
377
|
+
"Machinating",
|
|
378
|
+
"Whispering",
|
|
379
|
+
"Summoning",
|
|
380
|
+
"Brewing",
|
|
381
|
+
"Steeping",
|
|
382
|
+
"Percolating",
|
|
383
|
+
"Marinating",
|
|
384
|
+
"Fermenting",
|
|
385
|
+
"Incubating",
|
|
386
|
+
"Hatching",
|
|
387
|
+
"Gobbling",
|
|
388
|
+
"Nibbling",
|
|
389
|
+
"Munching",
|
|
390
|
+
"Chewing",
|
|
391
|
+
"Digesting",
|
|
392
|
+
"Rummaging",
|
|
393
|
+
"Scavenging",
|
|
394
|
+
"Foraging",
|
|
395
|
+
"Poking",
|
|
396
|
+
"Prodding",
|
|
397
|
+
"Tickling",
|
|
398
|
+
"Massaging",
|
|
399
|
+
"Jiggling",
|
|
400
|
+
"Shimmying",
|
|
401
|
+
"Scooting",
|
|
402
|
+
"Zipping",
|
|
403
|
+
"Zooming",
|
|
404
|
+
"Whizzing",
|
|
405
|
+
"Bleeping",
|
|
406
|
+
"Blooping",
|
|
407
|
+
"Beeping",
|
|
408
|
+
"Booping",
|
|
409
|
+
"Tinkering",
|
|
410
|
+
"Fiddling",
|
|
411
|
+
"Doodling",
|
|
412
|
+
"Noodling",
|
|
413
|
+
"Goblinizing",
|
|
414
|
+
"Wizarding",
|
|
415
|
+
"Enchanting",
|
|
416
|
+
"Spellcasting",
|
|
417
|
+
"Alchemizing",
|
|
418
|
+
"Treasure-hunting",
|
|
419
|
+
"Dragon-wrangling",
|
|
420
|
+
)
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
def _clean_words(items: Iterable[str]) -> tuple[str, ...]:
|
|
424
|
+
|
|
425
|
+
seen: set[str] = set()
|
|
426
|
+
out: list[str] = []
|
|
427
|
+
for it in items:
|
|
428
|
+
w = str(it or "").strip()
|
|
429
|
+
if not w:
|
|
430
|
+
continue
|
|
431
|
+
if " " in w:
|
|
432
|
+
continue
|
|
433
|
+
if not w.isalpha():
|
|
434
|
+
continue
|
|
435
|
+
if not w.lower().endswith("ing"):
|
|
436
|
+
continue
|
|
437
|
+
w = w[0].upper() + w[1:]
|
|
438
|
+
if w in seen:
|
|
439
|
+
continue
|
|
440
|
+
seen.add(w)
|
|
441
|
+
out.append(w)
|
|
442
|
+
return tuple(out)
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
STATUS_WORDS: tuple[str, ...] = _clean_words(_STATUS_WORDS_RAW)
|
|
446
|
+
|
|
447
|
+
if len(STATUS_WORDS) < 50: # pragma: no cover
|
|
448
|
+
STATUS_WORDS = ("Thinking", "Working", "Responding")
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
@dataclass
|
|
452
|
+
class _DeckRotator:
|
|
453
|
+
words: tuple[str, ...]
|
|
454
|
+
rng: random.Random
|
|
455
|
+
lock: threading.Lock = field(default_factory=threading.Lock)
|
|
456
|
+
deck: Deque[str] = field(default_factory=deque)
|
|
457
|
+
|
|
458
|
+
def next(self, *, default: str = "Thinking") -> str:
|
|
459
|
+
if not self.words:
|
|
460
|
+
return default
|
|
461
|
+
|
|
462
|
+
with self.lock:
|
|
463
|
+
if not self.deck:
|
|
464
|
+
items = list(self.words)
|
|
465
|
+
self.rng.shuffle(items)
|
|
466
|
+
self.deck.extend(items)
|
|
467
|
+
|
|
468
|
+
try:
|
|
469
|
+
return self.deck.popleft()
|
|
470
|
+
except Exception:
|
|
471
|
+
return default
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
@lru_cache(maxsize=1)
|
|
475
|
+
def _rotator() -> _DeckRotator:
|
|
476
|
+
seed = time.time_ns() & 0xFFFFFFFF
|
|
477
|
+
return _DeckRotator(words=STATUS_WORDS, rng=random.Random(seed))
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
def next_status_word(*, default: str = "Thinking") -> str:
|
|
481
|
+
return _rotator().next(default=default)
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
from functools import lru_cache
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
@lru_cache(maxsize=1)
|
|
5
|
-
def _ww() -> object | None:
|
|
6
|
-
try:
|
|
7
|
-
from wonderwords import RandomWord # type: ignore
|
|
8
|
-
|
|
9
|
-
return RandomWord()
|
|
10
|
-
except Exception:
|
|
11
|
-
return None
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def _to_present_participle(verb: str) -> str:
|
|
15
|
-
v = (verb or "").strip()
|
|
16
|
-
if not v:
|
|
17
|
-
return ""
|
|
18
|
-
w = v.lower()
|
|
19
|
-
|
|
20
|
-
# Common irregulars / spelling rules that a simple suffix approach misses.
|
|
21
|
-
irregular = {
|
|
22
|
-
"be": "being",
|
|
23
|
-
"see": "seeing",
|
|
24
|
-
"flee": "fleeing",
|
|
25
|
-
"knee": "kneeing",
|
|
26
|
-
"die": "dying",
|
|
27
|
-
"tie": "tying",
|
|
28
|
-
"lie": "lying",
|
|
29
|
-
}
|
|
30
|
-
if w in irregular:
|
|
31
|
-
return irregular[w].capitalize()
|
|
32
|
-
|
|
33
|
-
# ie -> ying (die -> dying).
|
|
34
|
-
if w.endswith("ie") and len(w) > 2:
|
|
35
|
-
return (w[:-2] + "ying").capitalize()
|
|
36
|
-
|
|
37
|
-
# Drop trailing e (make -> making), but keep ee/ye/oe (see -> seeing).
|
|
38
|
-
if w.endswith("e") and not w.endswith(("ee", "ye", "oe")) and len(w) > 1:
|
|
39
|
-
return (w[:-1] + "ing").capitalize()
|
|
40
|
-
|
|
41
|
-
# Verbs ending in 'ic' often add 'k' (panic -> panicking).
|
|
42
|
-
if w.endswith("ic") and len(w) > 2:
|
|
43
|
-
return (w + "king").capitalize()
|
|
44
|
-
|
|
45
|
-
vowels = set("aeiou")
|
|
46
|
-
# Double final consonant for short CVC words with a/i/o/u vowel (run -> running).
|
|
47
|
-
if (
|
|
48
|
-
3 <= len(w) <= 4
|
|
49
|
-
and w[-1] not in vowels
|
|
50
|
-
and w[-1] not in "wxy"
|
|
51
|
-
and w[-2] in vowels
|
|
52
|
-
and w[-2] != "e"
|
|
53
|
-
and w[-3] not in vowels
|
|
54
|
-
):
|
|
55
|
-
return (w + w[-1] + "ing").capitalize()
|
|
56
|
-
|
|
57
|
-
return (w + "ing").capitalize()
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
def random_verb(*, default: str = "Thinking") -> str:
|
|
61
|
-
"""Return a random present-participle verb for display (e.g. "Searching")."""
|
|
62
|
-
rw = _ww()
|
|
63
|
-
if rw is None:
|
|
64
|
-
return default
|
|
65
|
-
|
|
66
|
-
try:
|
|
67
|
-
# wonderwords supports parts_of_speech filtering.
|
|
68
|
-
word = rw.word(include_parts_of_speech=["verbs"]) # type: ignore[attr-defined]
|
|
69
|
-
word = str(word or "").strip()
|
|
70
|
-
if not word:
|
|
71
|
-
return default
|
|
72
|
-
ing = _to_present_participle(word)
|
|
73
|
-
return ing if ing else default
|
|
74
|
-
except Exception:
|
|
75
|
-
return default
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
# Backward-compat alias (older code used adjectives).
|
|
79
|
-
def random_adjective(*, default: str = "Curious") -> str: # pragma: no cover
|
|
80
|
-
return default
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|