corethink 1.0.0__tar.gz → 1.0.2__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.
Files changed (68) hide show
  1. {corethink-1.0.0 → corethink-1.0.2}/PKG-INFO +22 -7
  2. {corethink-1.0.0 → corethink-1.0.2}/README.md +18 -5
  3. {corethink-1.0.0 → corethink-1.0.2}/pyproject.toml +4 -2
  4. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/_version.py +1 -1
  5. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/commands/admin.py +183 -18
  6. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/commands/api.py +11 -1
  7. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/commands/archive.py +66 -11
  8. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/commands/auth.py +158 -13
  9. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/commands/billing.py +86 -8
  10. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/commands/capture.py +164 -20
  11. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/commands/connection.py +206 -33
  12. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/commands/endpoint.py +128 -25
  13. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/commands/env.py +298 -46
  14. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/commands/hub.py +67 -7
  15. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/commands/library.py +44 -4
  16. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/commands/models.py +50 -7
  17. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/commands/train.py +157 -23
  18. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/commands/workspace.py +211 -25
  19. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/main.py +67 -2
  20. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/output.py +31 -5
  21. {corethink-1.0.0 → corethink-1.0.2}/src/corethink.egg-info/PKG-INFO +22 -7
  22. {corethink-1.0.0 → corethink-1.0.2}/src/corethink.egg-info/SOURCES.txt +1 -0
  23. corethink-1.0.2/tests/test_main_json.py +10 -0
  24. {corethink-1.0.0 → corethink-1.0.2}/tests/test_train.py +39 -0
  25. {corethink-1.0.0 → corethink-1.0.2}/setup.cfg +0 -0
  26. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/__init__.py +0 -0
  27. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/__main__.py +0 -0
  28. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/account.py +0 -0
  29. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/cli.py +0 -0
  30. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/client.py +0 -0
  31. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/commands/__init__.py +0 -0
  32. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/config.py +0 -0
  33. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/context.py +0 -0
  34. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/env_template.py +0 -0
  35. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/environment_http_store.py +0 -0
  36. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/experiment_cli.py +0 -0
  37. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/hosted_profiles.py +0 -0
  38. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/hosted_rl.py +0 -0
  39. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/hosted_rl_archive.py +0 -0
  40. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/hosted_rl_attribution.py +0 -0
  41. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/hosted_rl_billing.py +0 -0
  42. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/hosted_rl_state.py +0 -0
  43. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/jobs_cli.py +0 -0
  44. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/py.typed +0 -0
  45. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/rl_cli.py +0 -0
  46. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/rl_inspect.py +0 -0
  47. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/rl_playground.py +0 -0
  48. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/rl_reassessment.py +0 -0
  49. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/rl_settings.py +0 -0
  50. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/sdk.py +0 -0
  51. {corethink-1.0.0 → corethink-1.0.2}/src/corethink/settings.py +0 -0
  52. {corethink-1.0.0 → corethink-1.0.2}/src/corethink.egg-info/dependency_links.txt +0 -0
  53. {corethink-1.0.0 → corethink-1.0.2}/src/corethink.egg-info/entry_points.txt +0 -0
  54. {corethink-1.0.0 → corethink-1.0.2}/src/corethink.egg-info/requires.txt +0 -0
  55. {corethink-1.0.0 → corethink-1.0.2}/src/corethink.egg-info/top_level.txt +0 -0
  56. {corethink-1.0.0 → corethink-1.0.2}/tests/test_admin.py +0 -0
  57. {corethink-1.0.0 → corethink-1.0.2}/tests/test_archive.py +0 -0
  58. {corethink-1.0.0 → corethink-1.0.2}/tests/test_auth.py +0 -0
  59. {corethink-1.0.0 → corethink-1.0.2}/tests/test_billing.py +0 -0
  60. {corethink-1.0.0 → corethink-1.0.2}/tests/test_capture.py +0 -0
  61. {corethink-1.0.0 → corethink-1.0.2}/tests/test_connection.py +0 -0
  62. {corethink-1.0.0 → corethink-1.0.2}/tests/test_endpoint.py +0 -0
  63. {corethink-1.0.0 → corethink-1.0.2}/tests/test_env.py +0 -0
  64. {corethink-1.0.0 → corethink-1.0.2}/tests/test_hub.py +0 -0
  65. {corethink-1.0.0 → corethink-1.0.2}/tests/test_library.py +0 -0
  66. {corethink-1.0.0 → corethink-1.0.2}/tests/test_models.py +0 -0
  67. {corethink-1.0.0 → corethink-1.0.2}/tests/test_version.py +0 -0
  68. {corethink-1.0.0 → corethink-1.0.2}/tests/test_workspace.py +0 -0
@@ -1,11 +1,12 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: corethink
3
- Version: 1.0.0
3
+ Version: 1.0.2
4
4
  Summary: The CoreThink Workbench from your terminal: environments, training, endpoints and more.
5
5
  Author-email: CoreThink <support@corethink.ai>
6
6
  License-Expression: MIT
7
7
  Project-URL: Homepage, https://corethink.ai
8
- Project-URL: Documentation, https://workbench.corethink.ai/app/docs
8
+ Project-URL: Documentation, https://corethink.ai/docs/workbench-cli
9
+ Project-URL: Reference, https://corethink.ai/docs/workbench-cli-reference
9
10
  Project-URL: Console, https://workbench.corethink.ai
10
11
  Keywords: corethink,workbench,llm,agents,cli,training
11
12
  Classifier: Development Status :: 5 - Production/Stable
@@ -18,6 +19,7 @@ Classifier: Programming Language :: Python :: 3.10
18
19
  Classifier: Programming Language :: Python :: 3.11
19
20
  Classifier: Programming Language :: Python :: 3.12
20
21
  Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Programming Language :: Python :: 3.14
21
23
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
22
24
  Classifier: Topic :: Software Development
23
25
  Requires-Python: >=3.10
@@ -33,12 +35,24 @@ small models, check them against the base model, release them and call them —
33
35
  scriptable.
34
36
 
35
37
  ```bash
36
- pip install corethink # or: pipx install corethink / uv tool install corethink
38
+ pipx install corethink # or: uv tool install corethink
37
39
  corethink login # opens your browser to approve this terminal
38
40
  corethink env list
39
41
  ```
40
42
 
41
- Python 3.10 or newer, on Linux, macOS and Windows.
43
+ Python 3.10 or newer, on Linux, macOS and Windows. **Docs:** [guide](https://corethink.ai/docs/workbench-cli) ·
44
+ [every command](https://corethink.ai/docs/workbench-cli-reference)
45
+
46
+ ## Install
47
+
48
+ | Where | How |
49
+ | --- | --- |
50
+ | Your machine | `pipx install corethink` or `uv tool install corethink` |
51
+ | A virtual environment, conda, Docker or CI | `pip install corethink` |
52
+ | Upgrade | `pipx upgrade corethink`, `uv tool upgrade corethink` or `pip install -U corethink` |
53
+
54
+ `error: externally-managed-environment` from pip means your system Python (recent Ubuntu, Debian, Fedora, Homebrew)
55
+ does not take packages: use pipx or uv as above. On Ubuntu: `sudo apt install pipx && pipx ensurepath`.
42
56
 
43
57
  ## Quick start
44
58
 
@@ -90,8 +104,8 @@ Make a token once (`corethink token create github-actions`, or in the Workbench:
90
104
  as `CORETHINK_TOKEN`. No login or config file is needed then:
91
105
 
92
106
  ```yaml
93
- - run: pip install corethink
94
- - run: corethink train start payroll --limit 10 --yes --json > run.json
107
+ - run: pipx install corethink
108
+ - run: corethink train start payroll --limit 10 --yes --watch # fails the step if the run fails
95
109
  env:
96
110
  CORETHINK_TOKEN: ${{ secrets.CORETHINK_TOKEN }}
97
111
  ```
@@ -117,4 +131,5 @@ Shell completion: `corethink --install-completion`.
117
131
 
118
132
  ## Help
119
133
 
120
- Docs: <https://workbench.corethink.ai/app/docs> · Support: support@corethink.ai
134
+ Guide: <https://corethink.ai/docs/workbench-cli> · Every command: <https://corethink.ai/docs/workbench-cli-reference> ·
135
+ Workbench docs: <https://workbench.corethink.ai/app/docs> · Support: support@corethink.ai
@@ -5,12 +5,24 @@ small models, check them against the base model, release them and call them —
5
5
  scriptable.
6
6
 
7
7
  ```bash
8
- pip install corethink # or: pipx install corethink / uv tool install corethink
8
+ pipx install corethink # or: uv tool install corethink
9
9
  corethink login # opens your browser to approve this terminal
10
10
  corethink env list
11
11
  ```
12
12
 
13
- Python 3.10 or newer, on Linux, macOS and Windows.
13
+ Python 3.10 or newer, on Linux, macOS and Windows. **Docs:** [guide](https://corethink.ai/docs/workbench-cli) ·
14
+ [every command](https://corethink.ai/docs/workbench-cli-reference)
15
+
16
+ ## Install
17
+
18
+ | Where | How |
19
+ | --- | --- |
20
+ | Your machine | `pipx install corethink` or `uv tool install corethink` |
21
+ | A virtual environment, conda, Docker or CI | `pip install corethink` |
22
+ | Upgrade | `pipx upgrade corethink`, `uv tool upgrade corethink` or `pip install -U corethink` |
23
+
24
+ `error: externally-managed-environment` from pip means your system Python (recent Ubuntu, Debian, Fedora, Homebrew)
25
+ does not take packages: use pipx or uv as above. On Ubuntu: `sudo apt install pipx && pipx ensurepath`.
14
26
 
15
27
  ## Quick start
16
28
 
@@ -62,8 +74,8 @@ Make a token once (`corethink token create github-actions`, or in the Workbench:
62
74
  as `CORETHINK_TOKEN`. No login or config file is needed then:
63
75
 
64
76
  ```yaml
65
- - run: pip install corethink
66
- - run: corethink train start payroll --limit 10 --yes --json > run.json
77
+ - run: pipx install corethink
78
+ - run: corethink train start payroll --limit 10 --yes --watch # fails the step if the run fails
67
79
  env:
68
80
  CORETHINK_TOKEN: ${{ secrets.CORETHINK_TOKEN }}
69
81
  ```
@@ -89,4 +101,5 @@ Shell completion: `corethink --install-completion`.
89
101
 
90
102
  ## Help
91
103
 
92
- Docs: <https://workbench.corethink.ai/app/docs> · Support: support@corethink.ai
104
+ Guide: <https://corethink.ai/docs/workbench-cli> · Every command: <https://corethink.ai/docs/workbench-cli-reference> ·
105
+ Workbench docs: <https://workbench.corethink.ai/app/docs> · Support: support@corethink.ai
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "corethink"
7
- version = "1.0.0"
7
+ version = "1.0.2"
8
8
  description = "The CoreThink Workbench from your terminal: environments, training, endpoints and more."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -22,6 +22,7 @@ classifiers = [
22
22
  "Programming Language :: Python :: 3.11",
23
23
  "Programming Language :: Python :: 3.12",
24
24
  "Programming Language :: Python :: 3.13",
25
+ "Programming Language :: Python :: 3.14",
25
26
  "Topic :: Scientific/Engineering :: Artificial Intelligence",
26
27
  "Topic :: Software Development",
27
28
  ]
@@ -33,7 +34,8 @@ dependencies = [
33
34
 
34
35
  [project.urls]
35
36
  Homepage = "https://corethink.ai"
36
- Documentation = "https://workbench.corethink.ai/app/docs"
37
+ Documentation = "https://corethink.ai/docs/workbench-cli"
38
+ Reference = "https://corethink.ai/docs/workbench-cli-reference"
37
39
  Console = "https://workbench.corethink.ai"
38
40
 
39
41
  [project.scripts]
@@ -1,3 +1,3 @@
1
1
  """The version of the `corethink` package (read by the build and by `corethink --version`)."""
2
2
 
3
- __version__ = "1.0.0"
3
+ __version__ = "1.0.2"
@@ -19,9 +19,55 @@ from corethink.client import ApiError
19
19
  from corethink.commands.workspace import entry_amount, entry_type
20
20
  from corethink.context import client
21
21
 
22
- app = typer.Typer(help="Every account and run on this Workbench (super admins only).", no_args_is_help=True)
23
- settings_app = typer.Typer(help="Account limits for everyone: show them, or change them with `set`.")
24
- superadmins_app = typer.Typer(help="Who can use the admin commands and page.")
22
+ HELP = """Every account and run on this Workbench (super admins only).
23
+
24
+ These commands look across every account and workspace on the Workbench, not just your own. Only super
25
+ admins can use them; anyone else is told they cannot. `corethink admin superadmins` shows who can and
26
+ manages the list.
27
+
28
+ A typical flow: `corethink admin overview` for the totals, `corethink admin accounts` to find someone,
29
+ `corethink admin account` to see one account in full, then `corethink admin add-credit` to give it credit
30
+ or `corethink admin limits` to change its own limits. `corethink admin settings` holds the limits for every
31
+ account. `corethink admin runs` and `corethink admin logs` look into any workspace's runs, and
32
+ `corethink admin waitlist` shows who asked to join.
33
+
34
+ Adding credit and changing limits ask for confirmation unless `--yes` is given.
35
+
36
+ Examples:
37
+ corethink admin overview
38
+ corethink admin accounts --search acme.com
39
+ corethink admin add-credit ana@acme.com 50 --note "Pilot credit"
40
+ corethink admin runs --status failed
41
+ """
42
+
43
+ SETTINGS_HELP = """Account limits for everyone: show them, or change them with `set`.
44
+
45
+ `corethink admin settings` alone shows each limit: its name and key, its value (marked `(default)` when it
46
+ was never changed), the default, the allowed range and whether it can also be set for one account. The
47
+ limits are the welcome credit a new account gets, how many welcome credits are given per day, how many runs
48
+ can go at once in a personal and in a team workspace, and the smallest and largest spending limit of a run.
49
+
50
+ Change them with `corethink admin settings set`; give one account its own values with
51
+ `corethink admin limits`.
52
+
53
+ Examples:
54
+ corethink admin settings
55
+ corethink admin settings set signupCreditUsd=10 maxRunningJobs=3
56
+ """
57
+
58
+ SUPERADMINS_HELP = """Who can use the admin commands and page.
59
+
60
+ `corethink admin superadmins` alone lists them, as `list` does. `add` makes someone a super admin and
61
+ `remove` takes it away. The Workbench's team owners are always super admins and cannot be removed here.
62
+
63
+ Examples:
64
+ corethink admin superadmins
65
+ corethink admin superadmins add ana@acme.com --notify
66
+ """
67
+
68
+ app = typer.Typer(help=HELP, no_args_is_help=True)
69
+ settings_app = typer.Typer(help=SETTINGS_HELP)
70
+ superadmins_app = typer.Typer(help=SUPERADMINS_HELP)
25
71
 
26
72
  YES_OPTION = typer.Option(False, "--yes", "-y", help="Do not ask.")
27
73
  JOB_ID = re.compile(r"^[0-9a-f-]{36}$")
@@ -155,7 +201,20 @@ def _change_text(values: dict[str, Any], units: dict[str, Any]) -> str:
155
201
 
156
202
  @app.command("overview")
157
203
  def overview() -> None:
158
- """Accounts, runs, spend and credit across the Workbench."""
204
+ """Show totals across the Workbench: accounts, runs, spend and credit.
205
+
206
+ Accounts: the total, how many confirmed their email, how many are new in the last 7 days, and sign-ups
207
+ per day. Runs: running, queued, finished in the last 7 days (succeeded and failed) and the total. Spend
208
+ and credit: spent on runs overall and in the last 7 days; credit given or bought (welcome credit, added
209
+ by admins, bought); and how much is used, left and held by running jobs. Test accounts and their runs
210
+ are not counted.
211
+
212
+ With `--json` it returns `accounts`, `runs`, `spend` and `credit`. Look at accounts with
213
+ `corethink admin accounts` and runs with `corethink admin runs`.
214
+
215
+ Examples:
216
+ corethink admin overview
217
+ """
159
218
  data = _call("GET", "/api/v1/admin/overview")
160
219
  accounts, runs = data.get("accounts") or {}, data.get("runs") or {}
161
220
  spend, credit = data.get("spend") or {}, data.get("credit") or {}
@@ -228,9 +287,18 @@ def accounts(
228
287
  search: str = typer.Option(None, "--search", "-s", help="Only accounts whose email contains this."),
229
288
  limit: int = typer.Option(100, "--limit", "-n", min=1, help="Show at most this many."),
230
289
  ) -> None:
231
- """Every account, newest first.
290
+ """List every account on the Workbench, newest first.
232
291
 
233
- Example: corethink admin accounts --search acme.com
292
+ Shows each account's email, when it was created, whether its email is confirmed, how many workspaces it
293
+ is in, its balance, what it spent, its number of runs and its ID. `--search` keeps accounts whose email
294
+ contains the text; `--limit` shows at most that many. Test accounts are hidden.
295
+
296
+ With `--json` it returns `accounts` (those shown), `total` and `hiddenTestAccounts`. See one in full
297
+ with `corethink admin account`.
298
+
299
+ Examples:
300
+ corethink admin accounts
301
+ corethink admin accounts --search acme.com
234
302
  """
235
303
  data = _call("GET", "/api/v1/admin/accounts")
236
304
  every = data.get("accounts") or []
@@ -273,7 +341,19 @@ def accounts(
273
341
  def account(
274
342
  who: str = typer.Argument(..., metavar="ACCOUNT", help="The account's email or ID (or the start of either)."),
275
343
  ) -> None:
276
- """One account: its workspaces, credit, limits and runs."""
344
+ """Show one account: its workspaces, credit, limits and runs.
345
+
346
+ Find the account by its email or ID, or the start of either. Shows its email, ID, when it was created,
347
+ whether it is confirmed, its balance (and how much running jobs hold) and what it spent on runs. Then
348
+ its workspaces with its role in each, its limits (the value in use, its own value and the value for
349
+ everyone), its 20 newest credit entries and its 20 newest runs.
350
+
351
+ With `--json` it returns `account`, `workspaces`, `limits`, `ledger` and `runs`. Give it credit with
352
+ `corethink admin add-credit`, or change its limits with `corethink admin limits`.
353
+
354
+ Examples:
355
+ corethink admin account ana@acme.com
356
+ """
277
357
  found = _find_account(who)
278
358
  detail = _call("GET", f"/api/v1/admin/accounts/{found['uid']}")
279
359
  shown = detail.get("account") or found
@@ -368,7 +448,17 @@ def add_credit(
368
448
  ) -> None:
369
449
  """Add promotional credit to an account.
370
450
 
371
- Example: corethink admin add-credit ana@acme.com 50 --note "Pilot credit"
451
+ Adds up to $1,000 to the account's balance, with a note that its credit history shows (`--note` is
452
+ required). Asks for confirmation unless `--yes` is given. Each credit has a unique key (`--key`, a new
453
+ one by default): sending the same request again with the same key adds nothing, so a retried script
454
+ cannot add the credit twice.
455
+
456
+ With `--json` it returns `uid`, `email`, `key`, the new `balanceUsd` and, when the key was already used,
457
+ `repeated`. Check the result with `corethink admin account`.
458
+
459
+ Examples:
460
+ corethink admin add-credit ana@acme.com 50 --note "Pilot credit"
461
+ corethink admin add-credit ana@acme.com 50 --note "Pilot credit" --key pilot-ana-2026 --yes
372
462
  """
373
463
  if not 0 < usd <= 1000:
374
464
  ui.error("Give an amount from $0.01 to $1,000.")
@@ -405,9 +495,18 @@ def limits(
405
495
  ),
406
496
  yes: bool = YES_OPTION,
407
497
  ) -> None:
408
- """Show an account's own limits, or set them.
498
+ """Show or set one account's own limits.
499
+
500
+ Without KEY=VALUE pairs it shows the account's limits: each limit's name and key, the value in use, the
501
+ account's own value (if it has one) and the value for everyone. With pairs it sets the account's own
502
+ values; the value `default` removes its own value, so the value for everyone applies again. Keys may be
503
+ written in any case or with dashes. `corethink admin settings` shows which limits can be set per account.
504
+
505
+ Setting asks for confirmation unless `--yes` is given. With `--json` it returns the account's `limits`.
409
506
 
410
- Example: corethink admin limits ana@acme.com maxRunningJobs=5 maxBudgetUsd=default
507
+ Examples:
508
+ corethink admin limits ana@acme.com
509
+ corethink admin limits ana@acme.com maxRunningJobs=5 maxBudgetUsd=default
411
510
  """
412
511
  found = _find_account(who)
413
512
  current = _call("GET", f"/api/v1/admin/accounts/{found['uid']}").get("limits") or {}
@@ -477,7 +576,16 @@ def settings_set(
477
576
  ) -> None:
478
577
  """Change limits for every account; limits left out stay as they are.
479
578
 
480
- Example: corethink admin settings set signupCreditUsd=10 maxRunningJobs=3
579
+ Give KEY=VALUE pairs with the keys `corethink admin settings` shows, in any case or with dashes. The
580
+ value `default` goes back to the default. Each value must be in the allowed range that
581
+ `corethink admin settings` shows. An account with its own value for a limit keeps it.
582
+
583
+ Asks for confirmation unless `--yes` is given, then shows the limits as saved. With `--json` it returns
584
+ the saved settings, with `limits`.
585
+
586
+ Examples:
587
+ corethink admin settings set signupCreditUsd=10 maxRunningJobs=3
588
+ corethink admin settings set max-budget-usd=default --yes
481
589
  """
482
590
  current = _call("GET", "/api/v1/admin/settings")
483
591
  rows = current.get("limits") or []
@@ -511,9 +619,20 @@ def runs(
511
619
  ),
512
620
  limit: int = typer.Option(50, "--limit", "-n", min=1, help="Show at most this many."),
513
621
  ) -> None:
514
- """Every workspace's runs, newest first.
622
+ """List every workspace's runs, newest first.
623
+
624
+ Shows each run's job ID, who started it, its workspace and environment, its kind, its status (running,
625
+ starting, queued, paused, succeeded, failed or cancelled), its stage, what it spent of its limit and when
626
+ it started. `--status` keeps `running`, `queued` (with paused), `succeeded` or `failed` (with cancelled)
627
+ runs. `--search` matches the person, workspace, environment or job ID. Test accounts' runs are hidden
628
+ unless `--qa` is given, and then marked QA.
515
629
 
516
- Example: corethink admin runs --status failed
630
+ With `--json` it returns `runs` (those shown) and notes such as `hiddenTestRuns` and `capped`. Download
631
+ a run's logs with `corethink admin logs`.
632
+
633
+ Examples:
634
+ corethink admin runs --status failed
635
+ corethink admin runs --search acme.com --limit 20
517
636
  """
518
637
  if status is not None and status.lower() not in RUN_FILTERS:
519
638
  ui.error(f"--status: use one of {', '.join(RUN_FILTERS)}.")
@@ -574,7 +693,20 @@ def logs(
574
693
  help="Where to save the .tar.gz (default run-<job>-logs.tar.gz here); - for stdout.",
575
694
  ),
576
695
  ) -> None:
577
- """Download a run's logs (its record, hold and log files) as one .tar.gz, from any workspace."""
696
+ """Download a run's logs, from any workspace, as one .tar.gz file.
697
+
698
+ The file holds the run's record and credit hold, its status files, each stage's log, the training pods'
699
+ output and the calls it made through connections. Give the job ID or the start of it (as
700
+ `corethink admin runs` shows it). It is saved as `run-JOB-logs.tar.gz` in the current folder unless
701
+ `--output` names another file; `--output -` writes it to stdout.
702
+
703
+ With `--json` it returns `jobId`, `path` and `bytes`.
704
+
705
+ Examples:
706
+ corethink admin logs 3f2a
707
+ corethink admin logs 3f2a -o run.tar.gz
708
+ corethink admin logs 3f2a -o - | tar -tz
709
+ """
578
710
  job = job_id.strip().lower()
579
711
  if not JOB_ID.fullmatch(job):
580
712
  every = _call("GET", "/api/v1/admin/runs", qa=1).get("runs") or []
@@ -610,7 +742,14 @@ def superadmins_default(ctx: typer.Context) -> None:
610
742
 
611
743
  @superadmins_app.command("list")
612
744
  def superadmins_list() -> None:
613
- """The super admins."""
745
+ """List the super admins.
746
+
747
+ Shows each super admin's email (yours marked), whether they are a team owner, have joined or have not
748
+ signed up yet, who added them and when. With `--json` it returns `admins` and `you`.
749
+
750
+ Examples:
751
+ corethink admin superadmins list
752
+ """
614
753
  data = _call("GET", "/api/v1/admin/superadmins")
615
754
  you = data.get("you")
616
755
 
@@ -640,7 +779,16 @@ def superadmins_add(
640
779
  email: str = typer.Argument(..., help="Their email address."),
641
780
  notify: bool = typer.Option(False, "--notify", help="Also email them that they were added (off by default)."),
642
781
  ) -> None:
643
- """Make someone a super admin. They get access once they sign up with this email."""
782
+ """Make someone a super admin.
783
+
784
+ They get access to the admin commands and page once they sign up with this email. No email is sent
785
+ unless `--notify` is given. It does not ask for confirmation. Check the list with
786
+ `corethink admin superadmins list`.
787
+
788
+ Examples:
789
+ corethink admin superadmins add ana@acme.com
790
+ corethink admin superadmins add ana@acme.com --notify
791
+ """
644
792
  done = _call("POST", "/api/v1/admin/superadmins", {"email": email.strip(), "notify": notify})
645
793
  ui.emit(
646
794
  done,
@@ -655,7 +803,14 @@ def superadmins_remove(
655
803
  email: str = typer.Argument(..., help="Their email address."),
656
804
  yes: bool = YES_OPTION,
657
805
  ) -> None:
658
- """Take away someone's super admin access."""
806
+ """Take away someone's super admin access.
807
+
808
+ Asks for confirmation unless `--yes` is given. The Workbench's team owners cannot be removed, and you
809
+ cannot remove yourself.
810
+
811
+ Examples:
812
+ corethink admin superadmins remove ana@acme.com
813
+ """
659
814
  ui.confirm(f"Remove {email.strip()} as a super admin?", yes=yes)
660
815
  done = _call("DELETE", "/api/v1/admin/superadmins", {"email": email.strip()})
661
816
  ui.emit(
@@ -671,7 +826,17 @@ def superadmins_remove(
671
826
  def waitlist(
672
827
  pending: bool = typer.Option(False, "--pending", help="Only people not sent the beta email yet."),
673
828
  ) -> None:
674
- """The waitlist: who asked to join and who was sent the beta email (read only)."""
829
+ """Show the waitlist: who asked to join and who got the beta email.
830
+
831
+ Shows whether sign-up is open to everyone or by invitation only, then each person's email (test
832
+ addresses marked), where they came from, when they joined the waitlist and when they were sent the beta
833
+ email. `--pending` keeps only people not sent it yet. This command only reads; it sends nothing.
834
+
835
+ With `--json` it returns `open` and `entries`.
836
+
837
+ Examples:
838
+ corethink admin waitlist --pending
839
+ """
675
840
  data = _call("GET", "/api/v1/waitlist")
676
841
  entries = [e for e in data.get("entries") or [] if not pending or not e.get("invitedAt")]
677
842
 
@@ -22,7 +22,17 @@ def api(
22
22
  ) -> None:
23
23
  """Call any Workbench API route directly and print its JSON answer.
24
24
 
25
- Example: corethink api GET /api/v1/harnesses/training-jobs -p qa=1
25
+ For what the other commands do not cover yet: everything the console does goes through this API, and this command
26
+ calls it as you, with your session, in the open workspace. A path without `/api/` is taken as under `/api/v1/`.
27
+ The answer is printed as JSON whatever `--json` says; an error answer exits with the error's message.
28
+
29
+ It does what the route does: a POST, PUT, PATCH or DELETE changes things (and may spend credit) as the same
30
+ action in the console would. Prefer the named commands when there is one.
31
+
32
+ Examples:
33
+ corethink api GET /api/v1/harnesses/training-jobs -p qa=1
34
+ corethink api GET harnesses/usecases
35
+ corethink api POST harnesses/training-jobs -d @run.json
26
36
  """
27
37
  verb = method.upper()
28
38
  if verb not in METHODS:
@@ -27,8 +27,28 @@ from corethink.commands.train import (
27
27
  )
28
28
  from corethink.context import client
29
29
 
30
+ HELP = """Archived runs, tests and environments: restore them, or delete them for good.
31
+
32
+ Archiving takes a finished run or test, or a whole environment, out of the lists without losing anything:
33
+ `corethink train archive` archives a run or test, and `corethink env archive` an environment with every
34
+ run and test on it. An archived run's or environment's endpoint keeps serving what it served when it was
35
+ archived. Archiving can be undone at any time with `corethink archive restore`.
36
+
37
+ Deleting is different: `corethink archive delete` and `corethink archive delete-all` remove archived
38
+ things for good, with their logs, files and endpoints, and cannot be undone. Only archived things can be
39
+ deleted, and only admins can delete. Each delete first shows what it would remove and asks you to
40
+ confirm. Credit already spent stays in the ledger.
41
+
42
+ Members can restore runs and tests; restoring an environment needs an admin.
43
+
44
+ Examples:
45
+ corethink archive list
46
+ corethink archive restore 3f2a
47
+ corethink archive delete 3f2a
48
+ """
49
+
30
50
  app = typer.Typer(
31
- help="Archived runs, tests and environments: restore them, or delete them for good.",
51
+ help=HELP,
32
52
  no_args_is_help=True,
33
53
  rich_markup_mode="rich",
34
54
  )
@@ -68,9 +88,19 @@ def _archived(at: Any, by: Any) -> str:
68
88
 
69
89
  @app.command("list")
70
90
  def list_archive() -> None:
71
- """Archived environments, runs and tests in this workspace.
91
+ """List the archived environments, runs and tests in this workspace.
92
+
93
+ Archived environments show their ID, name, how many runs and tests were archived with them, and when
94
+ and by whom they were archived. Archived runs and tests show their ID, name, kind (training run or
95
+ base-model test), environment, result (a finished run's score before and after training, or a test's
96
+ score) and when they were archived, noting those archived with their environment.
97
+
98
+ With `--json` it returns `environments` and `runs`. Bring one back with `corethink archive restore`,
99
+ or remove it for good with `corethink archive delete`.
72
100
 
73
- Example: corethink archive list
101
+ Examples:
102
+ corethink archive list
103
+ corethink --json archive list
74
104
  """
75
105
  archive = load_archive()
76
106
 
@@ -198,7 +228,14 @@ def restore(
198
228
  environment: bool = typer.Option(False, "--env", help="It is an environment."),
199
229
  run: bool = typer.Option(False, "--run", help="It is a run or test."),
200
230
  ) -> None:
201
- """Bring an archived run, test or environment back (an environment comes back with the runs archived with it).
231
+ """Bring back an archived run, test or environment.
232
+
233
+ It returns to the lists as it was. An environment comes back with the runs and tests archived with it.
234
+ A run or test whose environment is archived cannot come back alone: restore the environment instead.
235
+ Members can restore runs and tests; restoring an environment needs an admin.
236
+
237
+ Give the ID or its start, or a run's name, as `corethink archive list` shows it. Environments are
238
+ matched first; `--env` or `--run` says which kind you mean.
202
239
 
203
240
  Examples:
204
241
  corethink archive restore 3f2a
@@ -287,12 +324,22 @@ def delete(
287
324
  run: bool = typer.Option(False, "--run", help="It is a run or test."),
288
325
  yes: bool = typer.Option(False, "--yes", "-y", help="Delete without asking."),
289
326
  ) -> None:
290
- """Delete an archived run, test or environment for good (admins). Shows what would go first.
327
+ """Delete an archived run, test or environment for good (admins).
328
+
329
+ First shows what would be removed, as the Workbench counts it. For a run or test: its record, logs,
330
+ charts, final check and files, and its learned program's package with what its endpoint serves from
331
+ it, unless something else still uses them. An environment also takes its archived runs and tests, its
332
+ endpoint (staging, canaries and keys: callers using those keys stop working) and its own files (tasks,
333
+ tools, traces, captured conversations and labels).
291
334
 
292
- An environment takes its archived runs and tests, its endpoint (staging, keys) and its files with it.
293
- This cannot be undone.
335
+ Then you confirm by typing the run's short ID (its first 8 characters) or the environment's ID. `--yes`
336
+ skips this, and is required when there is no terminal to type in. This cannot be undone. Only archived
337
+ things can be deleted, and the Workbench may refuse, saying why. With `--json` it returns the summary
338
+ of what was deleted.
294
339
 
295
- Example: corethink archive delete 3f2a
340
+ Examples:
341
+ corethink archive delete 3f2a
342
+ corethink archive delete payroll-0ecb50 --env --yes
296
343
  """
297
344
  if environment and run:
298
345
  raise fail("Choose --env or --run, not both.")
@@ -360,11 +407,19 @@ def delete_all(
360
407
  what: str = typer.Argument(..., help="runs (archived runs and tests) or environments."),
361
408
  yes: bool = typer.Option(False, "--yes", "-y", help="Delete without asking."),
362
409
  ) -> None:
363
- """Delete every archived run and test, or every archived environment, for good (admins).
410
+ """Delete every archived run and test, or every archived environment (admins).
411
+
412
+ Say `runs` (archived runs and tests) or `environments`. It first shows what would be removed, then asks:
413
+ a yes-or-no question for runs; for environments you type `delete all`. `--yes` skips this, and is
414
+ required when there is no terminal. This cannot be undone. Credit already spent stays in the ledger.
364
415
 
365
- Any that cannot be deleted are skipped and listed. Spent credit stays in the ledger. This cannot be undone.
416
+ They are deleted a few at a time. Any that cannot be deleted are skipped and listed with the reason,
417
+ and the command then exits with status 1. With `--json` it returns `asked`, `deleted`, `failed` (each
418
+ with its reason) and `stopped` (why it stopped early, if it did).
366
419
 
367
- Example: corethink archive delete-all runs
420
+ Examples:
421
+ corethink archive delete-all runs
422
+ corethink archive delete-all environments --yes
368
423
  """
369
424
  if what not in ("runs", "environments"):
370
425
  raise fail("Say what to delete: runs or environments.")