oai-workbench-cli 0.1.0__py3-none-any.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.
- oai_workbench_cli-0.1.0.dist-info/METADATA +369 -0
- oai_workbench_cli-0.1.0.dist-info/RECORD +35 -0
- oai_workbench_cli-0.1.0.dist-info/WHEEL +4 -0
- oai_workbench_cli-0.1.0.dist-info/entry_points.txt +2 -0
- oai_workbench_cli-0.1.0.dist-info/licenses/LICENSE +21 -0
- openai_py_cli/__init__.py +3 -0
- openai_py_cli/cli.py +82 -0
- openai_py_cli/client.py +50 -0
- openai_py_cli/commands/__init__.py +1 -0
- openai_py_cli/commands/ask.py +210 -0
- openai_py_cli/commands/batch.py +120 -0
- openai_py_cli/commands/chat.py +121 -0
- openai_py_cli/commands/code_review.py +66 -0
- openai_py_cli/commands/compare.py +182 -0
- openai_py_cli/commands/config_cmd.py +55 -0
- openai_py_cli/commands/doctor.py +94 -0
- openai_py_cli/commands/eval_cmd.py +145 -0
- openai_py_cli/commands/explain_error.py +56 -0
- openai_py_cli/commands/files.py +95 -0
- openai_py_cli/commands/json_mode.py +107 -0
- openai_py_cli/commands/logs.py +123 -0
- openai_py_cli/commands/models.py +71 -0
- openai_py_cli/commands/profile.py +92 -0
- openai_py_cli/commands/prompt_lint.py +210 -0
- openai_py_cli/commands/redact.py +25 -0
- openai_py_cli/commands/replay.py +100 -0
- openai_py_cli/config.py +140 -0
- openai_py_cli/dry_run.py +27 -0
- openai_py_cli/errors.py +41 -0
- openai_py_cli/logging_store.py +165 -0
- openai_py_cli/output.py +35 -0
- openai_py_cli/pricing.py +35 -0
- openai_py_cli/redaction.py +81 -0
- openai_py_cli/runtime.py +16 -0
- openai_py_cli/schema_validation.py +65 -0
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: oai-workbench-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Developer-first CLI wrapper around the official OpenAI Python SDK.
|
|
5
|
+
Author: oai-cli contributors
|
|
6
|
+
License: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Keywords: cli,developer-tools,openai,rich,typer
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Environment :: Console
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Software Development
|
|
18
|
+
Requires-Python: <3.13,>=3.10
|
|
19
|
+
Requires-Dist: jsonschema>=4.22.0
|
|
20
|
+
Requires-Dist: openai>=1.0.0
|
|
21
|
+
Requires-Dist: platformdirs>=4.2.0
|
|
22
|
+
Requires-Dist: pydantic>=2.6.0
|
|
23
|
+
Requires-Dist: rich>=13.7.0
|
|
24
|
+
Requires-Dist: tomli>=2.0.1; python_version < '3.11'
|
|
25
|
+
Requires-Dist: typer>=0.12.0
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: mypy>=1.10.0; extra == 'dev'
|
|
28
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
29
|
+
Requires-Dist: ruff>=0.5.0; extra == 'dev'
|
|
30
|
+
Requires-Dist: types-jsonschema>=4.24.0; extra == 'dev'
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
# oai-cli
|
|
34
|
+
|
|
35
|
+
Developer-first CLI for the OpenAI API, built on top of the official `openai-python` SDK.
|
|
36
|
+
|
|
37
|
+
`oai-cli` is designed for day-to-day engineering work: quick prompts, dry-run payload inspection, local request logs, model comparisons, JSON schema validation, file and batch helpers, prompt linting, redaction, and AI-assisted review workflows from pipes.
|
|
38
|
+
|
|
39
|
+
## Highlights
|
|
40
|
+
|
|
41
|
+
- One-shot prompts with the Responses API: `oai-cli ask`
|
|
42
|
+
- Interactive streaming chat REPL: `oai-cli chat`
|
|
43
|
+
- Safe payload previews with `--dry-run`
|
|
44
|
+
- Local SQLite request history, replay, export, and secret scanning
|
|
45
|
+
- Local redaction for API keys, bearer tokens, JWTs, emails, phone numbers, cookies, private keys, and tokenized URLs
|
|
46
|
+
- Prompt linting without API calls
|
|
47
|
+
- Model comparison and eval runs across multiple models
|
|
48
|
+
- Strict JSON mode with JSON Schema validation
|
|
49
|
+
- Files and Batch API helpers
|
|
50
|
+
- Pipe-friendly code review and traceback explanation commands
|
|
51
|
+
- Profiles that store environment variable names, not plaintext API keys
|
|
52
|
+
|
|
53
|
+
## Requirements
|
|
54
|
+
|
|
55
|
+
- Python `3.10`, `3.11`, or `3.12`
|
|
56
|
+
- An OpenAI API key exported through an environment variable
|
|
57
|
+
|
|
58
|
+
Python `3.13+` is intentionally not advertised yet because several upstream dependencies may be unstable there.
|
|
59
|
+
|
|
60
|
+
## Installation
|
|
61
|
+
|
|
62
|
+
From PyPI:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pip install oai-workbench-cli
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The installed console command is still `oai-cli`.
|
|
69
|
+
|
|
70
|
+
For isolated CLI installation:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pipx install oai-workbench-cli
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
From a local checkout:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
cd /path/to/oai-cli
|
|
80
|
+
pip install .
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
For development:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
python -m venv .venv
|
|
87
|
+
source .venv/bin/activate
|
|
88
|
+
pip install -e ".[dev]"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Quickstart
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
export OPENAI_API_KEY=...
|
|
95
|
+
|
|
96
|
+
oai-cli config init
|
|
97
|
+
oai-cli doctor --check-api
|
|
98
|
+
oai-cli ask --no-stream "Reply with OK only."
|
|
99
|
+
oai-cli ask --dry-run "Explain this payload"
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Fish shell:
|
|
103
|
+
|
|
104
|
+
```fish
|
|
105
|
+
set -gx OPENAI_API_KEY 'your_key_here'
|
|
106
|
+
oai-cli doctor --check-api
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Do not paste API keys into issues, chats, shell history, or committed files.
|
|
110
|
+
|
|
111
|
+
## Global Options
|
|
112
|
+
|
|
113
|
+
Global options must appear before the command:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
oai-cli --timeout 30 ask "Reply briefly"
|
|
117
|
+
oai-cli --plain doctor
|
|
118
|
+
oai-cli --json doctor
|
|
119
|
+
oai-cli --debug ask "Show traceback for expected CLI errors"
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
`--debug` can show tracebacks. Use it locally and avoid sharing output that may include sensitive data.
|
|
123
|
+
|
|
124
|
+
## Configuration
|
|
125
|
+
|
|
126
|
+
Initialize config:
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
oai-cli config init
|
|
130
|
+
oai-cli config show
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Default config paths:
|
|
134
|
+
|
|
135
|
+
- Linux/macOS: `~/.config/oai-cli/config.toml`
|
|
136
|
+
- Windows: platform app config directory via `platformdirs`
|
|
137
|
+
|
|
138
|
+
The CLI stores the name of the environment variable, not the API key value.
|
|
139
|
+
|
|
140
|
+
Profiles:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
oai-cli profile list
|
|
144
|
+
oai-cli profile create work --api-key-env OPENAI_WORK_API_KEY --model gpt-4.1
|
|
145
|
+
oai-cli profile use work
|
|
146
|
+
oai-cli profile show
|
|
147
|
+
oai-cli profile delete work
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Supported config fields:
|
|
151
|
+
|
|
152
|
+
- `default_model`
|
|
153
|
+
- `api_key_env`
|
|
154
|
+
- `base_url`
|
|
155
|
+
- `organization`
|
|
156
|
+
- `project`
|
|
157
|
+
- `log_enabled`
|
|
158
|
+
- `log_path`
|
|
159
|
+
- `redact_enabled`
|
|
160
|
+
- `active_profile`
|
|
161
|
+
- `profiles`
|
|
162
|
+
|
|
163
|
+
## Ask
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
oai-cli ask "Explain Python context managers"
|
|
167
|
+
cat prompt.txt | oai-cli ask --model gpt-4.1-mini
|
|
168
|
+
oai-cli ask --system "You are concise." --temperature 0.2 "Summarize this"
|
|
169
|
+
oai-cli ask --dry-run "Show request payload only"
|
|
170
|
+
oai-cli ask --cost-estimate "Estimate input cost"
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Key options:
|
|
174
|
+
|
|
175
|
+
- `--model`, `-m`
|
|
176
|
+
- `--system`
|
|
177
|
+
- `--temperature`
|
|
178
|
+
- `--max-output-tokens`
|
|
179
|
+
- `--stream / --no-stream`
|
|
180
|
+
- `--json`
|
|
181
|
+
- `--dry-run`
|
|
182
|
+
- `--cost-estimate`
|
|
183
|
+
- `--save / --no-save`
|
|
184
|
+
- `--redact / --no-redact`
|
|
185
|
+
|
|
186
|
+
## Chat
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
oai-cli chat --model gpt-4.1-mini
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
REPL commands:
|
|
193
|
+
|
|
194
|
+
```text
|
|
195
|
+
/help
|
|
196
|
+
/exit
|
|
197
|
+
/clear
|
|
198
|
+
/model <name>
|
|
199
|
+
/system <text>
|
|
200
|
+
/save <name>
|
|
201
|
+
/load <name>
|
|
202
|
+
/history
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
For multiline input, enter `"""`, then type lines, then close with `"""`.
|
|
206
|
+
|
|
207
|
+
## Redaction
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
oai-cli redact "Bearer abcdef1234567890"
|
|
211
|
+
cat file.txt | oai-cli redact
|
|
212
|
+
cat file.txt | oai-cli redact --json
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Redaction is local. It detects common secrets including OpenAI keys, JWTs, bearer tokens, GitHub tokens, generic API keys, cookies, private key PEM blocks, emails, phone numbers, and query-string tokens.
|
|
216
|
+
|
|
217
|
+
## Logs And Replay
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
oai-cli logs list
|
|
221
|
+
oai-cli logs show <id>
|
|
222
|
+
oai-cli logs export --format jsonl
|
|
223
|
+
oai-cli logs scan-secrets
|
|
224
|
+
oai-cli replay <id> --dry-run
|
|
225
|
+
oai-cli replay <id> --model gpt-4.1 --yes
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Logs are stored in SQLite under the platform data directory unless `log_path` is configured.
|
|
229
|
+
|
|
230
|
+
## Compare
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
oai-cli compare "Summarize this release note" -m gpt-4.1-mini -m gpt-4.1
|
|
234
|
+
oai-cli compare --dry-run "Show payload only" -m gpt-4.1-mini -m gpt-4.1
|
|
235
|
+
oai-cli compare "Prompt" -m gpt-4.1-mini -m gpt-4.1 --diff
|
|
236
|
+
oai-cli compare "Prompt" -m gpt-4.1-mini -m gpt-4.1 --json-output result.json
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Prompt Lint
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
oai-cli prompt-lint prompt.txt
|
|
243
|
+
cat prompt.txt | oai-cli prompt-lint --json
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
The linter is local-only and reports:
|
|
247
|
+
|
|
248
|
+
- score from `0` to `100`
|
|
249
|
+
- warnings
|
|
250
|
+
- suggestions
|
|
251
|
+
- improved prompt draft
|
|
252
|
+
|
|
253
|
+
It checks for vague wording, missing output format, missing constraints, conflicting instructions, overly long prompts, hidden requirements, possible secrets, and JSON requests without schema.
|
|
254
|
+
|
|
255
|
+
## JSON Mode
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
oai-cli json "Extract invoice fields" --schema schema.json
|
|
259
|
+
oai-cli json "Extract invoice fields" --schema schema.json --retry 2 --output result.json
|
|
260
|
+
oai-cli json "Show payload" --schema schema.json --dry-run
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
The command validates the schema locally, asks the model for JSON-only output, parses the response, and validates it against the schema before printing or writing it.
|
|
264
|
+
|
|
265
|
+
## Files
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
oai-cli files list
|
|
269
|
+
oai-cli files upload data.jsonl --purpose batch
|
|
270
|
+
oai-cli files retrieve file_...
|
|
271
|
+
oai-cli files delete file_...
|
|
272
|
+
oai-cli files download file_... --output out.bin
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## Batch
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
oai-cli batch create requests.jsonl --endpoint /v1/responses --completion-window 24h
|
|
279
|
+
oai-cli batch create requests.jsonl --dry-run
|
|
280
|
+
oai-cli batch status batch_...
|
|
281
|
+
oai-cli batch list
|
|
282
|
+
oai-cli batch cancel batch_...
|
|
283
|
+
oai-cli batch download batch_... --output result.jsonl
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
`batch create` validates JSONL locally, shows row count, and previews the first row before upload.
|
|
287
|
+
|
|
288
|
+
## Models
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
oai-cli models list --refresh
|
|
292
|
+
oai-cli models cache
|
|
293
|
+
oai-cli models list
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
`models list` uses the local cache unless `--refresh` is passed or no cache exists.
|
|
297
|
+
|
|
298
|
+
## Eval
|
|
299
|
+
|
|
300
|
+
Create a JSONL file:
|
|
301
|
+
|
|
302
|
+
```jsonl
|
|
303
|
+
{"id":"case-1","prompt":"Summarize this in one sentence: ..."}
|
|
304
|
+
{"id":"case-2","prompt":"Extract the company name: ..."}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Run it:
|
|
308
|
+
|
|
309
|
+
```bash
|
|
310
|
+
oai-cli eval cases.jsonl -m gpt-4.1-mini -m gpt-4.1 --output eval-results.json
|
|
311
|
+
oai-cli eval cases.jsonl -m gpt-4.1-mini --dry-run
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
## Code Review
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
git diff | oai-cli code-review
|
|
318
|
+
git diff | oai-cli code-review --focus security --output json
|
|
319
|
+
git diff | oai-cli code-review --dry-run
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
Redaction is enabled before sending the diff.
|
|
323
|
+
|
|
324
|
+
## Explain Error
|
|
325
|
+
|
|
326
|
+
```bash
|
|
327
|
+
pytest 2>&1 | oai-cli explain-error
|
|
328
|
+
pytest 2>&1 | oai-cli explain-error --dry-run
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
Redaction is enabled before sending logs.
|
|
332
|
+
|
|
333
|
+
## Doctor
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
oai-cli doctor
|
|
337
|
+
oai-cli doctor --check-api
|
|
338
|
+
oai-cli doctor --json
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
Checks Python version, package version, SDK version, active profile, API key environment variable, base URL, config/log directories, and optionally a minimal API request.
|
|
342
|
+
|
|
343
|
+
## Exit Codes
|
|
344
|
+
|
|
345
|
+
- `0`: success
|
|
346
|
+
- `1`: general error
|
|
347
|
+
- `2`: config error
|
|
348
|
+
- `3`: API error
|
|
349
|
+
- `4`: validation error
|
|
350
|
+
|
|
351
|
+
## Security Notes
|
|
352
|
+
|
|
353
|
+
- API keys are read from environment variables.
|
|
354
|
+
- API key values are not printed in dry-run output.
|
|
355
|
+
- API keys are not stored in config by default.
|
|
356
|
+
- Redaction is enabled by default for sensitive workflows.
|
|
357
|
+
- If a key is pasted into a chat, issue, PR, terminal transcript, or committed file, revoke it and create a new one.
|
|
358
|
+
|
|
359
|
+
## Development
|
|
360
|
+
|
|
361
|
+
```bash
|
|
362
|
+
python -m venv .venv
|
|
363
|
+
source .venv/bin/activate
|
|
364
|
+
pip install -e ".[dev]"
|
|
365
|
+
|
|
366
|
+
ruff check openai_py_cli tests
|
|
367
|
+
pytest
|
|
368
|
+
mypy openai_py_cli
|
|
369
|
+
```
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
openai_py_cli/__init__.py,sha256=TbSN46sra_u4sSlaiXNqi6Iy-wcy5V0xQtYb8I22m5Y,93
|
|
2
|
+
openai_py_cli/cli.py,sha256=nBY6L_s6gGskcnheTpPb-iYRFOFZtPxc7P82mcH7LcY,2094
|
|
3
|
+
openai_py_cli/client.py,sha256=0vP1AAA4bjXLBBz-gwuMeaM8J-2BWZWC8qLOIvLyIU0,1330
|
|
4
|
+
openai_py_cli/config.py,sha256=HkR7lO-_9C2Lg1AJPXWDrqjetCZIR1KqJeTfkAFTjAA,4591
|
|
5
|
+
openai_py_cli/dry_run.py,sha256=2VUPalDUCh2xLxJHGbBB4zlOcqvqRCvNXieZCCCtCmk,648
|
|
6
|
+
openai_py_cli/errors.py,sha256=YFba3GJtvuCrALktuZWniR1Lx8LdLP0h70YpP3KhS3s,842
|
|
7
|
+
openai_py_cli/logging_store.py,sha256=-rJ83N2XoJmyKlH32t_GZwCMhdEqwGN-RNEUkUR0rQY,5387
|
|
8
|
+
openai_py_cli/output.py,sha256=n252oYDP7J8YjOqPF_x2qZTl1zrXAABaOoJJMcGHlLM,895
|
|
9
|
+
openai_py_cli/pricing.py,sha256=-Jjwk0-uQMb06ZmfXkGGdZ97EIXP5aMxE67meU-qQas,949
|
|
10
|
+
openai_py_cli/redaction.py,sha256=LNbGsPESipD_kuQQ1nBiVn6nZOBgrgyaFoaoWurA_f4,2176
|
|
11
|
+
openai_py_cli/runtime.py,sha256=5gmNHmZOKPGwGkj-iPYArYW-TJ9ejjnz8m2fqcWz_ns,286
|
|
12
|
+
openai_py_cli/schema_validation.py,sha256=5x_2k4zdPRJYJfJjiwc8sBCDq_2zRlMUddGarROy3Bo,2328
|
|
13
|
+
openai_py_cli/commands/__init__.py,sha256=gQ6tnU0Rvm0-ESWFUBU-KDl5dpNOpUTG509hXOQQjwY,27
|
|
14
|
+
openai_py_cli/commands/ask.py,sha256=UAh0VloX5s7vJ4dKg6uzUxb6cvhP41-x7Cefi_BEtRU,6776
|
|
15
|
+
openai_py_cli/commands/batch.py,sha256=zi6RT7rtfIyZFdoq8K61rETVAaoXuarLWT7EzuzNFlo,4034
|
|
16
|
+
openai_py_cli/commands/chat.py,sha256=moIus0rdhEhBO0z84BBVnBgp35lGcZtlh38hMKmOKwg,4099
|
|
17
|
+
openai_py_cli/commands/code_review.py,sha256=WRTMtiVOnQoI0HoLNtzHBvr6_UH1AINxAJ8sM9dnRoU,2609
|
|
18
|
+
openai_py_cli/commands/compare.py,sha256=rFbhzMkKAs8ACwGMxL5pDmJcSH8Dlps0q3FIIwthwX8,6229
|
|
19
|
+
openai_py_cli/commands/config_cmd.py,sha256=EWe0EXgoodIM121j1sSizL3pVMvBvrkYeAI4Ph0ryHA,1672
|
|
20
|
+
openai_py_cli/commands/doctor.py,sha256=sBzqgLmMMZi2hkm5YEs34NLW7b0En7_2wwXRQzm4mP8,3015
|
|
21
|
+
openai_py_cli/commands/eval_cmd.py,sha256=Ss2g42Wk-x0aQNUA6tw9uEkSfKit1y9fdvfb3iAotNk,4800
|
|
22
|
+
openai_py_cli/commands/explain_error.py,sha256=nmk9ldSidfKWOse7nvqy2M2CP2aGq-fa3FbmiLVKeDE,1946
|
|
23
|
+
openai_py_cli/commands/files.py,sha256=ORkHwz4TNxbmyqzeSAbuUFx-bjVz-ln1hOKdu_T89CU,3259
|
|
24
|
+
openai_py_cli/commands/json_mode.py,sha256=e7Kjj7aX9gSi8MPm_BaAnx03nsXqPyXD-XlOvrR1q_Q,3580
|
|
25
|
+
openai_py_cli/commands/logs.py,sha256=dAStj_Lqi2pie6ktDXp5X2i3mqbDiNjEyUFWibXbtdk,3738
|
|
26
|
+
openai_py_cli/commands/models.py,sha256=wBcLZfxB017C-WC3rcJe-TMclRPYRetbqM3ou60VXn4,2279
|
|
27
|
+
openai_py_cli/commands/profile.py,sha256=Xe--7LhSkRfBoGSq30-EPrVwauwqUSwc4WxB38ZlH-A,2789
|
|
28
|
+
openai_py_cli/commands/prompt_lint.py,sha256=L98l34q6W-8TPpHnyX0fcm-w1pRh0gIrpSc7aBFyqec,6445
|
|
29
|
+
openai_py_cli/commands/redact.py,sha256=Wo6ZPJM-hgrcjJfsp64Vgz3caThEqGqB8-BUGr8c37Y,705
|
|
30
|
+
openai_py_cli/commands/replay.py,sha256=iUSDq40VVR-gaQUppTC_pVllYQv0S2gFUehcD2zEvYs,3677
|
|
31
|
+
oai_workbench_cli-0.1.0.dist-info/METADATA,sha256=fprIhSuebjxFW_5i48IgtBYnuRaIQFUf82GGRHrYyfY,9009
|
|
32
|
+
oai_workbench_cli-0.1.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
33
|
+
oai_workbench_cli-0.1.0.dist-info/entry_points.txt,sha256=tYWXFjcXFw6Zi2kBXKKSyC_qm6WMGk_eUvNJznsXU1c,51
|
|
34
|
+
oai_workbench_cli-0.1.0.dist-info/licenses/LICENSE,sha256=icMQscwmqK97s-GnHAPKemnGXteId1Bc4fa31KM6hvA,1079
|
|
35
|
+
oai_workbench_cli-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 openai-py contributors
|
|
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.
|
openai_py_cli/cli.py
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"""CLI entrypoint."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
import typer
|
|
8
|
+
|
|
9
|
+
from .commands import (
|
|
10
|
+
ask,
|
|
11
|
+
batch,
|
|
12
|
+
chat,
|
|
13
|
+
code_review,
|
|
14
|
+
compare,
|
|
15
|
+
config_cmd,
|
|
16
|
+
doctor,
|
|
17
|
+
eval_cmd,
|
|
18
|
+
explain_error,
|
|
19
|
+
files,
|
|
20
|
+
json_mode,
|
|
21
|
+
logs,
|
|
22
|
+
models,
|
|
23
|
+
profile,
|
|
24
|
+
prompt_lint,
|
|
25
|
+
redact,
|
|
26
|
+
replay,
|
|
27
|
+
)
|
|
28
|
+
from .errors import OpenAIPyCliError
|
|
29
|
+
from .output import print_error
|
|
30
|
+
from .runtime import options
|
|
31
|
+
|
|
32
|
+
app = typer.Typer(
|
|
33
|
+
name="oai-cli",
|
|
34
|
+
help="Developer-first CLI wrapper around the official OpenAI Python SDK.",
|
|
35
|
+
no_args_is_help=True,
|
|
36
|
+
rich_markup_mode="rich",
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@app.callback()
|
|
41
|
+
def global_options(
|
|
42
|
+
debug: bool = typer.Option(False, "--debug", help="Show traceback for expected errors."),
|
|
43
|
+
timeout: float | None = typer.Option(None, "--timeout", help="OpenAI request timeout seconds."),
|
|
44
|
+
plain: bool = typer.Option(False, "--plain", help="Prefer plain text for machine parsing."),
|
|
45
|
+
json_output: bool = typer.Option(False, "--json", help="Prefer JSON for global errors."),
|
|
46
|
+
) -> None:
|
|
47
|
+
options.debug = debug
|
|
48
|
+
options.timeout = timeout
|
|
49
|
+
options.plain = plain
|
|
50
|
+
options.json_output = json_output
|
|
51
|
+
|
|
52
|
+
app.command("ask")(ask.ask)
|
|
53
|
+
app.command("redact")(redact.redact)
|
|
54
|
+
app.command("doctor")(doctor.doctor)
|
|
55
|
+
app.command("replay")(replay.replay)
|
|
56
|
+
app.command("compare")(compare.compare)
|
|
57
|
+
app.command("prompt-lint")(prompt_lint.prompt_lint)
|
|
58
|
+
app.command("chat")(chat.chat)
|
|
59
|
+
app.command("json")(json_mode.json_command)
|
|
60
|
+
app.command("code-review")(code_review.code_review)
|
|
61
|
+
app.command("explain-error")(explain_error.explain_error)
|
|
62
|
+
app.command("eval")(eval_cmd.eval_command)
|
|
63
|
+
app.add_typer(files.app, name="files")
|
|
64
|
+
app.add_typer(batch.app, name="batch")
|
|
65
|
+
app.add_typer(logs.app, name="logs")
|
|
66
|
+
app.add_typer(profile.app, name="profile")
|
|
67
|
+
app.add_typer(config_cmd.app, name="config")
|
|
68
|
+
app.add_typer(models.app, name="models")
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def main() -> None:
|
|
72
|
+
try:
|
|
73
|
+
app()
|
|
74
|
+
except OpenAIPyCliError as exc:
|
|
75
|
+
if options.debug:
|
|
76
|
+
raise
|
|
77
|
+
print_error(str(exc))
|
|
78
|
+
sys.exit(exc.exit_code)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
if __name__ == "__main__":
|
|
82
|
+
main()
|
openai_py_cli/client.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""OpenAI SDK client creation."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from .config import AppConfig, Profile, load_config
|
|
10
|
+
from .errors import MissingApiKeyError
|
|
11
|
+
from .runtime import options
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass(frozen=True)
|
|
15
|
+
class ClientContext:
|
|
16
|
+
config: AppConfig
|
|
17
|
+
profile_name: str
|
|
18
|
+
profile: Profile
|
|
19
|
+
api_key_env: str
|
|
20
|
+
api_key_present: bool
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def get_client(config: AppConfig | None = None) -> Any:
|
|
24
|
+
context = get_client_context(config)
|
|
25
|
+
api_key = os.environ.get(context.api_key_env)
|
|
26
|
+
if not api_key:
|
|
27
|
+
raise MissingApiKeyError(
|
|
28
|
+
f"{context.api_key_env} is not set. Run: export {context.api_key_env}=..."
|
|
29
|
+
)
|
|
30
|
+
from openai import OpenAI
|
|
31
|
+
|
|
32
|
+
return OpenAI(
|
|
33
|
+
api_key=api_key,
|
|
34
|
+
base_url=context.profile.base_url,
|
|
35
|
+
organization=context.profile.organization,
|
|
36
|
+
project=context.profile.project,
|
|
37
|
+
timeout=options.timeout,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def get_client_context(config: AppConfig | None = None) -> ClientContext:
|
|
42
|
+
cfg = config or load_config()
|
|
43
|
+
profile = cfg.active()
|
|
44
|
+
return ClientContext(
|
|
45
|
+
config=cfg,
|
|
46
|
+
profile_name=cfg.active_profile,
|
|
47
|
+
profile=profile,
|
|
48
|
+
api_key_env=profile.api_key_env,
|
|
49
|
+
api_key_present=bool(os.environ.get(profile.api_key_env)),
|
|
50
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""CLI command modules."""
|