ostruct-cli 0.7.2__tar.gz → 0.8.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/LICENSE +2 -0
- ostruct_cli-0.8.0/PKG-INFO +633 -0
- ostruct_cli-0.8.0/README.md +571 -0
- ostruct_cli-0.8.0/pyproject.toml +141 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/__init__.py +21 -3
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/base_errors.py +1 -1
- ostruct_cli-0.8.0/src/ostruct/cli/cli.py +141 -0
- ostruct_cli-0.8.0/src/ostruct/cli/click_options.py +807 -0
- ostruct_cli-0.8.0/src/ostruct/cli/code_interpreter.py +238 -0
- ostruct_cli-0.8.0/src/ostruct/cli/commands/__init__.py +32 -0
- ostruct_cli-0.8.0/src/ostruct/cli/commands/list_models.py +128 -0
- ostruct_cli-0.8.0/src/ostruct/cli/commands/quick_ref.py +50 -0
- ostruct_cli-0.8.0/src/ostruct/cli/commands/run.py +137 -0
- ostruct_cli-0.8.0/src/ostruct/cli/commands/update_registry.py +71 -0
- ostruct_cli-0.8.0/src/ostruct/cli/config.py +277 -0
- ostruct_cli-0.8.0/src/ostruct/cli/cost_estimation.py +134 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/errors.py +310 -6
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/exit_codes.py +1 -0
- ostruct_cli-0.8.0/src/ostruct/cli/explicit_file_processor.py +548 -0
- ostruct_cli-0.8.0/src/ostruct/cli/field_utils.py +69 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/file_info.py +42 -9
- ostruct_cli-0.8.0/src/ostruct/cli/file_list.py +525 -0
- ostruct_cli-0.8.0/src/ostruct/cli/file_search.py +455 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/file_utils.py +47 -13
- ostruct_cli-0.8.0/src/ostruct/cli/mcp_integration.py +541 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/model_creation.py +150 -1
- ostruct_cli-0.8.0/src/ostruct/cli/model_validation.py +204 -0
- ostruct_cli-0.8.0/src/ostruct/cli/progress_reporting.py +398 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/registry_updates.py +14 -9
- ostruct_cli-0.8.0/src/ostruct/cli/runner.py +1418 -0
- ostruct_cli-0.8.0/src/ostruct/cli/schema_utils.py +113 -0
- ostruct_cli-0.8.0/src/ostruct/cli/services.py +626 -0
- ostruct_cli-0.8.0/src/ostruct/cli/template_debug.py +748 -0
- ostruct_cli-0.8.0/src/ostruct/cli/template_debug_help.py +162 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/template_env.py +15 -6
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/template_filters.py +55 -3
- ostruct_cli-0.8.0/src/ostruct/cli/template_optimizer.py +474 -0
- ostruct_cli-0.8.0/src/ostruct/cli/template_processor.py +1080 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/template_rendering.py +69 -34
- ostruct_cli-0.8.0/src/ostruct/cli/token_validation.py +286 -0
- ostruct_cli-0.8.0/src/ostruct/cli/types.py +78 -0
- ostruct_cli-0.8.0/src/ostruct/cli/unattended_operation.py +269 -0
- ostruct_cli-0.8.0/src/ostruct/cli/validators.py +496 -0
- ostruct_cli-0.7.2/PKG-INFO +0 -370
- ostruct_cli-0.7.2/README.md +0 -340
- ostruct_cli-0.7.2/pyproject.toml +0 -127
- ostruct_cli-0.7.2/src/ostruct/cli/cli.py +0 -2058
- ostruct_cli-0.7.2/src/ostruct/cli/click_options.py +0 -375
- ostruct_cli-0.7.2/src/ostruct/cli/file_list.py +0 -326
- ostruct_cli-0.7.2/src/ostruct/cli/validators.py +0 -113
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/__init__.py +0 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/cache_manager.py +0 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/path_utils.py +0 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/progress.py +0 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/schema_validation.py +0 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/security/__init__.py +0 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/security/allowed_checker.py +0 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/security/base.py +0 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/security/case_manager.py +0 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/security/errors.py +0 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/security/normalization.py +0 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/security/safe_joiner.py +0 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/security/security_manager.py +0 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/security/symlink_resolver.py +0 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/security/types.py +0 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/security/windows_paths.py +0 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/serialization.py +0 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/template_extensions.py +0 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/template_io.py +0 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/template_schema.py +0 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/template_utils.py +0 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/template_validation.py +0 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/token_utils.py +0 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/cli/utils.py +0 -0
- {ostruct_cli-0.7.2 → ostruct_cli-0.8.0}/src/ostruct/py.typed +0 -0
@@ -0,0 +1,633 @@
|
|
1
|
+
Metadata-Version: 2.3
|
2
|
+
Name: ostruct-cli
|
3
|
+
Version: 0.8.0
|
4
|
+
Summary: CLI for OpenAI Structured Output with Multi-Tool Integration
|
5
|
+
Author: Yaniv Golan
|
6
|
+
Author-email: yaniv@golan.name
|
7
|
+
Requires-Python: >=3.10,<4.0
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
9
|
+
Classifier: Programming Language :: Python :: 3.10
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
13
|
+
Provides-Extra: dev
|
14
|
+
Provides-Extra: docs
|
15
|
+
Provides-Extra: examples
|
16
|
+
Requires-Dist: anyio[trio] (==3.7.1) ; extra == "dev"
|
17
|
+
Requires-Dist: asyncio-throttle (>=1.0.2,<2.0) ; extra == "examples"
|
18
|
+
Requires-Dist: black (==24.8.0) ; extra == "dev"
|
19
|
+
Requires-Dist: build (>=1.2.2.post1,<2.0) ; extra == "dev"
|
20
|
+
Requires-Dist: cachetools (>=5.3.2,<6.0)
|
21
|
+
Requires-Dist: chardet (>=5.0.0,<6.0)
|
22
|
+
Requires-Dist: click (>=8.1.7,<9.0)
|
23
|
+
Requires-Dist: flake8 (>=6.0,<7.0) ; extra == "dev"
|
24
|
+
Requires-Dist: flake8-pyproject (>=1.2.3,<2.0) ; extra == "dev"
|
25
|
+
Requires-Dist: ijson (>=3.2.3,<4.0)
|
26
|
+
Requires-Dist: jinja2 (>=3.1.2,<4.0)
|
27
|
+
Requires-Dist: jsonschema (>=4.23.0,<5.0)
|
28
|
+
Requires-Dist: mypy (>=1.0,<2.0) ; extra == "dev"
|
29
|
+
Requires-Dist: myst-parser (>=2.0.0,<3.0) ; extra == "docs"
|
30
|
+
Requires-Dist: openai (==1.81.0)
|
31
|
+
Requires-Dist: openai-model-registry (>=0.7.0,<1.0)
|
32
|
+
Requires-Dist: pre-commit (>=4.1.0,<5.0) ; extra == "dev"
|
33
|
+
Requires-Dist: psutil (>=7.0.0,<8.0) ; extra == "dev"
|
34
|
+
Requires-Dist: pydantic (>=2.6.3,<3.0)
|
35
|
+
Requires-Dist: pyfakefs (>=5.7.4,<6.0) ; extra == "dev"
|
36
|
+
Requires-Dist: pygments (>=2.15.0,<3.0)
|
37
|
+
Requires-Dist: pytest (>=8.3.4,<9.0) ; extra == "dev"
|
38
|
+
Requires-Dist: pytest-asyncio (>=0.25.2,<1.0) ; extra == "dev"
|
39
|
+
Requires-Dist: pytest-mock (>=3.14.0,<4.0) ; extra == "dev"
|
40
|
+
Requires-Dist: python-dotenv (>=1.0.1,<2.0) ; extra == "dev"
|
41
|
+
Requires-Dist: pyyaml (>=6.0.2,<7.0)
|
42
|
+
Requires-Dist: sphinx (>=7.0,<8.0) ; extra == "dev"
|
43
|
+
Requires-Dist: sphinx (>=7.0,<8.0) ; extra == "docs"
|
44
|
+
Requires-Dist: sphinx-design (>=0.5.0,<1.0) ; extra == "docs"
|
45
|
+
Requires-Dist: sphinx-rtd-theme (>=1.0,<2.0) ; extra == "docs"
|
46
|
+
Requires-Dist: tenacity (>=8.2.3,<9.0) ; extra == "examples"
|
47
|
+
Requires-Dist: tiktoken (==0.9.0)
|
48
|
+
Requires-Dist: tomli (>=2.0.1,<3.0) ; (python_version < "3.11") and (extra == "docs")
|
49
|
+
Requires-Dist: tomli (>=2.0.1,<3.0) ; python_version < "3.11"
|
50
|
+
Requires-Dist: twine (>=6.0.1,<7.0) ; extra == "dev"
|
51
|
+
Requires-Dist: types-cachetools (>=5.5.0.20240820) ; extra == "dev"
|
52
|
+
Requires-Dist: types-chardet (>=5.0.4.6) ; extra == "dev"
|
53
|
+
Requires-Dist: types-click (>=7.1.8,<8.0) ; extra == "dev"
|
54
|
+
Requires-Dist: types-jsonschema (>=4.23.0.20241208) ; extra == "dev"
|
55
|
+
Requires-Dist: types-pygments (>=2.19.0.20250107) ; extra == "dev"
|
56
|
+
Requires-Dist: types-pyyaml (>=6.0.12.20241230) ; extra == "dev"
|
57
|
+
Requires-Dist: types-requests (>=2.32.0.20241016) ; extra == "dev"
|
58
|
+
Requires-Dist: typing-extensions (>=4.9.0,<5.0)
|
59
|
+
Requires-Dist: werkzeug (>=3.1.3,<4.0)
|
60
|
+
Description-Content-Type: text/markdown
|
61
|
+
|
62
|
+
## 02:07 A.M. CI Failure
|
63
|
+
|
64
|
+
*"Build failed. Again. The third time this week our data extraction pipeline broke because someone changed the log format, and our regex-based parser couldn't handle the new structure. Sarah's on vacation, Mike's parsing code is unreadable, and the client wants their analytics dashboard working by morning.*
|
65
|
+
|
66
|
+
*There has to be a better way to turn messy data into structured JSON without writing custom parsers for every format change..."*
|
67
|
+
|
68
|
+
---
|
69
|
+
|
70
|
+

|
71
|
+
|
72
|
+
<div align="center">
|
73
|
+
|
74
|
+
[](https://badge.fury.io/py/ostruct-cli)
|
75
|
+
[](https://pypi.org/project/ostruct-cli)
|
76
|
+
[](https://ostruct.readthedocs.io/en/latest/?badge=latest)
|
77
|
+
[](https://github.com/yaniv-golan/ostruct/actions/workflows/ci.yml)
|
78
|
+
[](https://opensource.org/licenses/MIT)
|
79
|
+
[](https://pepy.tech/project/ostruct-cli)
|
80
|
+
[](https://github.com/psf/black)
|
81
|
+
|
82
|
+
**ostruct** transforms **unstructured** inputs into **structured**, usable **JSON** output using **OpenAI APIs** with **multi-tool integration**
|
83
|
+
|
84
|
+
*The better way you've been looking for.*
|
85
|
+
|
86
|
+
</div>
|
87
|
+
|
88
|
+
# ostruct-cli
|
89
|
+
|
90
|
+
ostruct processes unstructured data (text files, code, CSVs, etc.), input variables, and dynamic prompt templates to produce structured JSON output defined by a JSON schema. With enhanced multi-tool integration, ostruct now supports Code Interpreter for data analysis, File Search for document retrieval, and MCP (Model Context Protocol) servers for extended capabilities.
|
91
|
+
|
92
|
+
<div align="center">
|
93
|
+
|
94
|
+

|
95
|
+
|
96
|
+
</div>
|
97
|
+
|
98
|
+
## Why ostruct?
|
99
|
+
|
100
|
+
LLMs are powerful, but getting consistent, structured output from them can be challenging. ostruct solves this problem by providing a streamlined approach to transform unstructured data into reliable JSON structures. The motivation behind creating ostruct was to:
|
101
|
+
|
102
|
+
- **Bridge the gap** between freeform LLM capabilities and structured data needs in production systems
|
103
|
+
- **Simplify integration** of AI into existing workflows and applications that expect consistent data formats
|
104
|
+
- **Ensure reliability** and validate output against a defined schema to avoid unexpected formats or missing data
|
105
|
+
- **Reduce development time** by providing a standardized way to interact with OpenAI models for structured outputs
|
106
|
+
- **Enable non-developers** to leverage AI capabilities through a simple CLI interface with templates
|
107
|
+
|
108
|
+
## Real-World Use Cases
|
109
|
+
|
110
|
+
ostruct can be used for various scenarios, including:
|
111
|
+
|
112
|
+
### Automated Code Review with Multi-Tool Analysis
|
113
|
+
|
114
|
+
```bash
|
115
|
+
# Traditional pattern matching
|
116
|
+
ostruct run prompts/task.j2 schemas/code_review.json -p source "examples/security/*.py"
|
117
|
+
|
118
|
+
# Enhanced with Code Interpreter for deeper analysis
|
119
|
+
ostruct run prompts/task.j2 schemas/code_review.json -fc examples/security/ -fs documentation/
|
120
|
+
```
|
121
|
+
|
122
|
+
Analyze code for security vulnerabilities, style issues, and performance problems. The enhanced version uses Code Interpreter for execution analysis and File Search for documentation context.
|
123
|
+
|
124
|
+
### Security Vulnerability Scanning
|
125
|
+
|
126
|
+
```bash
|
127
|
+
# Budget-friendly static analysis (recommended for most projects)
|
128
|
+
ostruct run prompts/static_analysis.j2 schemas/scan_result.json \
|
129
|
+
-d code examples -R --sys-file prompts/system.txt
|
130
|
+
|
131
|
+
# Professional security analysis with Code Interpreter (best balance)
|
132
|
+
ostruct run prompts/code_interpreter.j2 schemas/scan_result.json \
|
133
|
+
-dc examples --sys-file prompts/system.txt
|
134
|
+
|
135
|
+
# Comprehensive hybrid analysis for critical applications
|
136
|
+
ostruct run prompts/hybrid_analysis.j2 schemas/scan_result.json \
|
137
|
+
-d code examples -R -dc examples --sys-file prompts/system.txt
|
138
|
+
```
|
139
|
+
|
140
|
+
**Three optimized approaches** for automated security vulnerability scanning:
|
141
|
+
|
142
|
+
- **Static Analysis**: $0.18 cost, fast processing, comprehensive vulnerability detection
|
143
|
+
- **Code Interpreter**: $0.18 cost (same!), superior analysis quality with evidence-based findings
|
144
|
+
- **Hybrid Analysis**: $0.20 cost (+13%), maximum depth with cross-validation
|
145
|
+
|
146
|
+
Each approach finds the same core vulnerabilities but with different levels of detail and analysis quality. Directory-based analysis provides comprehensive project coverage in a single scan.
|
147
|
+
|
148
|
+
### Data Analysis with Code Interpreter
|
149
|
+
|
150
|
+
```bash
|
151
|
+
# Upload data for analysis and visualization
|
152
|
+
ostruct run analysis.j2 schemas/analysis_result.json \
|
153
|
+
-fc sales_data.csv -fc customer_data.json \
|
154
|
+
-fs reports/ -ft config.yaml
|
155
|
+
```
|
156
|
+
|
157
|
+
Perform sophisticated data analysis using Python execution, generate visualizations, and create comprehensive reports with document context.
|
158
|
+
|
159
|
+
### Configuration Validation & Analysis
|
160
|
+
|
161
|
+
```bash
|
162
|
+
# Traditional file comparison
|
163
|
+
ostruct run prompts/task.j2 schemas/validation_result.json \
|
164
|
+
-f dev examples/basic/dev.yaml -f prod examples/basic/prod.yaml
|
165
|
+
|
166
|
+
# Enhanced with environment context
|
167
|
+
ostruct run prompts/task.j2 schemas/validation_result.json \
|
168
|
+
-ft dev.yaml -ft prod.yaml -fs infrastructure_docs/
|
169
|
+
```
|
170
|
+
|
171
|
+
Validate configuration files across environments with documentation context for better analysis and recommendations.
|
172
|
+
|
173
|
+
Oh, and also, among endless other use cases:
|
174
|
+
|
175
|
+
### Etymology Analysis
|
176
|
+
|
177
|
+
```bash
|
178
|
+
ostruct run prompts/task.j2 schemas/etymology.json -ft examples/scientific.txt
|
179
|
+
```
|
180
|
+
|
181
|
+
Break down words into their components, showing their origins, meanings, and hierarchical relationships. Useful for linguistics, educational tools, and understanding terminology in specialized fields.
|
182
|
+
|
183
|
+
## Features
|
184
|
+
|
185
|
+
### Core Capabilities
|
186
|
+
|
187
|
+
- Generate structured JSON output defined by dynamic prompts using OpenAI models and JSON schemas
|
188
|
+
- Rich template system for defining prompts (Jinja2-based)
|
189
|
+
- Automatic token counting and context window management
|
190
|
+
- Streaming support for real-time output
|
191
|
+
- Secure handling of sensitive data with comprehensive path validation
|
192
|
+
- Automatic prompt optimization and token management
|
193
|
+
|
194
|
+
### Multi-Tool Integration
|
195
|
+
|
196
|
+
- **Code Interpreter**: Upload and analyze data files, execute Python code, generate visualizations
|
197
|
+
- **File Search**: Vector-based document search and retrieval from uploaded files
|
198
|
+
- **MCP Servers**: Connect to Model Context Protocol servers for extended functionality
|
199
|
+
- **Explicit File Routing**: Route different files to specific tools for optimized processing
|
200
|
+
|
201
|
+
### Advanced Features
|
202
|
+
|
203
|
+
- **Configuration System**: YAML-based configuration with environment variable support
|
204
|
+
- **Unattended Operation**: Designed for CI/CD and automation scenarios
|
205
|
+
- **Progress Reporting**: Real-time progress updates with clear, user-friendly messaging
|
206
|
+
- **Model Registry**: Dynamic model management with support for latest OpenAI models
|
207
|
+
|
208
|
+
## Requirements
|
209
|
+
|
210
|
+
- Python 3.10 or higher
|
211
|
+
|
212
|
+
## Installation
|
213
|
+
|
214
|
+
### For Users
|
215
|
+
|
216
|
+
To install the latest stable version from PyPI:
|
217
|
+
|
218
|
+
```bash
|
219
|
+
pip install ostruct-cli
|
220
|
+
```
|
221
|
+
|
222
|
+
### For Developers
|
223
|
+
|
224
|
+
If you plan to contribute to the project, see the [Development Setup](#development-setup) section below for instructions on setting up the development environment with Poetry.
|
225
|
+
|
226
|
+
## Environment Variables
|
227
|
+
|
228
|
+
ostruct-cli respects the following environment variables:
|
229
|
+
|
230
|
+
- `OPENAI_API_KEY`: Your OpenAI API key (required unless provided via command line)
|
231
|
+
- `OPENAI_API_BASE`: Custom API base URL (optional)
|
232
|
+
- `OPENAI_API_VERSION`: API version to use (optional)
|
233
|
+
- `OPENAI_API_TYPE`: API type (e.g., "azure") (optional)
|
234
|
+
- `OSTRUCT_DISABLE_REGISTRY_UPDATE_CHECKS`: Set to "1", "true", or "yes" to disable automatic registry update checks
|
235
|
+
- `MCP_<NAME>_URL`: Custom MCP server URLs (e.g., `MCP_STRIPE_URL=https://mcp.stripe.com`)
|
236
|
+
|
237
|
+
<details>
|
238
|
+
<summary><strong>Shell Completion Setup</strong> (Click to expand)</summary>
|
239
|
+
|
240
|
+
ostruct-cli supports shell completion for Bash, Zsh, and Fish shells. To enable it:
|
241
|
+
|
242
|
+
### Bash
|
243
|
+
|
244
|
+
Add this to your `~/.bashrc`:
|
245
|
+
|
246
|
+
```bash
|
247
|
+
eval "$(_OSTRUCT_COMPLETE=bash_source ostruct)"
|
248
|
+
```
|
249
|
+
|
250
|
+
### Zsh
|
251
|
+
|
252
|
+
Add this to your `~/.zshrc`:
|
253
|
+
|
254
|
+
```bash
|
255
|
+
eval "$(_OSTRUCT_COMPLETE=zsh_source ostruct)"
|
256
|
+
```
|
257
|
+
|
258
|
+
### Fish
|
259
|
+
|
260
|
+
Add this to your `~/.config/fish/completions/ostruct.fish`:
|
261
|
+
|
262
|
+
```fish
|
263
|
+
eval (env _OSTRUCT_COMPLETE=fish_source ostruct)
|
264
|
+
```
|
265
|
+
|
266
|
+
After adding the appropriate line, restart your shell or source the configuration file.
|
267
|
+
Shell completion will help you with:
|
268
|
+
|
269
|
+
- Command options and their arguments
|
270
|
+
- File paths for template and schema files
|
271
|
+
- Directory paths for `-d` and `--base-dir` options
|
272
|
+
- And more!
|
273
|
+
|
274
|
+
</details>
|
275
|
+
|
276
|
+
## Enhanced CLI with Multi-Tool Integration
|
277
|
+
|
278
|
+
### Migration Notice
|
279
|
+
|
280
|
+
ostruct now includes powerful multi-tool integration while maintaining **full backward compatibility**. All existing commands continue to work exactly as before, but you can now take advantage of:
|
281
|
+
|
282
|
+
- **Code Interpreter** for data analysis and visualization
|
283
|
+
- **File Search** for document retrieval
|
284
|
+
- **MCP Servers** for extended functionality
|
285
|
+
- **Explicit File Routing** for optimized processing
|
286
|
+
|
287
|
+
<details>
|
288
|
+
<summary><strong>New File Routing Options</strong> (Click to expand)</summary>
|
289
|
+
|
290
|
+
#### Basic File Routing (Explicit Tool Assignment)
|
291
|
+
|
292
|
+
```bash
|
293
|
+
# Template access only (config files, small data)
|
294
|
+
ostruct run template.j2 schema.json -ft config.yaml
|
295
|
+
|
296
|
+
# Code Interpreter (data analysis, code execution)
|
297
|
+
ostruct run analysis.j2 schema.json -fc data.csv
|
298
|
+
|
299
|
+
# File Search (document retrieval)
|
300
|
+
ostruct run search.j2 schema.json -fs documentation.pdf
|
301
|
+
|
302
|
+
# Multiple tools with one file
|
303
|
+
ostruct run template.j2 schema.json --file-for code-interpreter shared.json --file-for file-search shared.json
|
304
|
+
```
|
305
|
+
|
306
|
+
#### Directory Routing
|
307
|
+
|
308
|
+
ostruct provides two directory routing patterns to match different use cases:
|
309
|
+
|
310
|
+
**Auto-Naming Pattern** (for known directory structures):
|
311
|
+
|
312
|
+
```bash
|
313
|
+
# Variables are auto-generated from directory contents
|
314
|
+
ostruct run template.j2 schema.json -dt ./config -dc ./datasets -ds ./docs
|
315
|
+
# Creates variables like: config_yaml, datasets_csv, docs_pdf (based on actual files)
|
316
|
+
```
|
317
|
+
|
318
|
+
**Alias Pattern** (for generic, reusable templates):
|
319
|
+
|
320
|
+
```bash
|
321
|
+
# Create stable variable names regardless of directory contents
|
322
|
+
ostruct run template.j2 schema.json --dta app_config ./config --dca data ./datasets --dsa knowledge ./docs
|
323
|
+
# Creates stable variables: app_config, data, knowledge (always these names)
|
324
|
+
```
|
325
|
+
|
326
|
+
**When to Use Each Pattern:**
|
327
|
+
|
328
|
+
- Use **auto-naming** (`-dt`, `-dc`, `-ds`) when your template knows the specific directory structure
|
329
|
+
- Use **alias syntax** (`--dta`, `--dca`, `--dsa`) when your template is generic and needs stable variable names
|
330
|
+
|
331
|
+
**Template Example:**
|
332
|
+
|
333
|
+
```jinja
|
334
|
+
{# Works with alias pattern - variables are predictable #}
|
335
|
+
{% for file in app_config %}
|
336
|
+
Configuration: {{ file.name }} = {{ file.content }}
|
337
|
+
{% endfor %}
|
338
|
+
|
339
|
+
{# Analysis data from stable variable name #}
|
340
|
+
{% for file in data %}
|
341
|
+
Processing: {{ file.path }}
|
342
|
+
{% endfor %}
|
343
|
+
```
|
344
|
+
|
345
|
+
This design pattern makes templates reusable across different projects while maintaining full backward compatibility.
|
346
|
+
|
347
|
+
#### MCP Server Integration
|
348
|
+
|
349
|
+
```bash
|
350
|
+
# Connect to MCP servers for extended capabilities
|
351
|
+
ostruct run template.j2 schema.json --mcp-server deepwiki@https://mcp.deepwiki.com/sse
|
352
|
+
```
|
353
|
+
|
354
|
+
</details>
|
355
|
+
|
356
|
+
### Configuration System
|
357
|
+
|
358
|
+
Create an `ostruct.yaml` file for persistent settings:
|
359
|
+
|
360
|
+
```yaml
|
361
|
+
models:
|
362
|
+
default: gpt-4o
|
363
|
+
|
364
|
+
tools:
|
365
|
+
code_interpreter:
|
366
|
+
auto_download: true
|
367
|
+
output_directory: "./output"
|
368
|
+
|
369
|
+
mcp:
|
370
|
+
custom_server: "https://my-mcp-server.com"
|
371
|
+
|
372
|
+
limits:
|
373
|
+
max_cost_per_run: 10.00
|
374
|
+
```
|
375
|
+
|
376
|
+
Load custom configuration:
|
377
|
+
|
378
|
+
```bash
|
379
|
+
ostruct --config my-config.yaml run template.j2 schema.json
|
380
|
+
```
|
381
|
+
|
382
|
+
## Get Started Quickly
|
383
|
+
|
384
|
+
🚀 **New to ostruct?** Follow our [step-by-step quickstart guide](https://ostruct.readthedocs.io/en/latest/user-guide/quickstart.html) featuring Juno the beagle for a hands-on introduction.
|
385
|
+
|
386
|
+
📖 **Full Documentation:** <https://ostruct.readthedocs.io/>
|
387
|
+
|
388
|
+
### Quick Start
|
389
|
+
|
390
|
+
1. Set your OpenAI API key:
|
391
|
+
|
392
|
+
```bash
|
393
|
+
export OPENAI_API_KEY=your-api-key
|
394
|
+
```
|
395
|
+
|
396
|
+
### Example 1: Basic Text Extraction (Simplest)
|
397
|
+
|
398
|
+
1. Create a template file `extract_person.j2`:
|
399
|
+
|
400
|
+
```jinja
|
401
|
+
Extract information about the person from this text: {{ stdin }}
|
402
|
+
```
|
403
|
+
|
404
|
+
2. Create a schema file `schema.json`:
|
405
|
+
|
406
|
+
```json
|
407
|
+
{
|
408
|
+
"type": "object",
|
409
|
+
"properties": {
|
410
|
+
"person": {
|
411
|
+
"type": "object",
|
412
|
+
"properties": {
|
413
|
+
"name": {"type": "string", "description": "The person's full name"},
|
414
|
+
"age": {"type": "integer", "description": "The person's age"},
|
415
|
+
"occupation": {"type": "string", "description": "The person's job"}
|
416
|
+
},
|
417
|
+
"required": ["name", "age", "occupation"],
|
418
|
+
"additionalProperties": false
|
419
|
+
}
|
420
|
+
},
|
421
|
+
"required": ["person"],
|
422
|
+
"additionalProperties": false
|
423
|
+
}
|
424
|
+
```
|
425
|
+
|
426
|
+
3. Run the CLI:
|
427
|
+
|
428
|
+
```bash
|
429
|
+
# Basic usage
|
430
|
+
echo "John Smith is a 35-year-old software engineer" | ostruct run extract_person.j2 schema.json
|
431
|
+
|
432
|
+
# With enhanced options
|
433
|
+
echo "John Smith is a 35-year-old software engineer" | \
|
434
|
+
ostruct run extract_person.j2 schema.json \
|
435
|
+
--model gpt-4o \
|
436
|
+
--temperature 0.7
|
437
|
+
```
|
438
|
+
|
439
|
+
### Example 2: Multi-Tool Data Analysis
|
440
|
+
|
441
|
+
1. Create an analysis template `analysis_template.j2`:
|
442
|
+
|
443
|
+
```jinja
|
444
|
+
Analyze the following data sources:
|
445
|
+
|
446
|
+
{% if sales_data_csv is defined %}
|
447
|
+
Sales Data: {{ sales_data_csv.name }} ({{ sales_data_csv.size }} bytes)
|
448
|
+
{% endif %}
|
449
|
+
|
450
|
+
{% if customer_data_json is defined %}
|
451
|
+
Customer Data: {{ customer_data_json.name }} ({{ customer_data_json.size }} bytes)
|
452
|
+
{% endif %}
|
453
|
+
|
454
|
+
{% if market_reports_pdf is defined %}
|
455
|
+
Market Reports: {{ market_reports_pdf.name }} ({{ market_reports_pdf.size }} bytes)
|
456
|
+
{% endif %}
|
457
|
+
|
458
|
+
{% if config_yaml is defined %}
|
459
|
+
Configuration: {{ config_yaml.content }}
|
460
|
+
{% endif %}
|
461
|
+
|
462
|
+
Provide comprehensive analysis and actionable insights.
|
463
|
+
```
|
464
|
+
|
465
|
+
2. Create an analysis schema `analysis_schema.json`:
|
466
|
+
|
467
|
+
```json
|
468
|
+
{
|
469
|
+
"type": "object",
|
470
|
+
"properties": {
|
471
|
+
"analysis": {
|
472
|
+
"type": "object",
|
473
|
+
"properties": {
|
474
|
+
"insights": {"type": "string", "description": "Key insights from the data"},
|
475
|
+
"recommendations": {
|
476
|
+
"type": "array",
|
477
|
+
"items": {"type": "string"},
|
478
|
+
"description": "Actionable recommendations"
|
479
|
+
},
|
480
|
+
"data_quality": {"type": "string", "description": "Assessment of data quality"}
|
481
|
+
},
|
482
|
+
"required": ["insights", "recommendations"],
|
483
|
+
"additionalProperties": false
|
484
|
+
}
|
485
|
+
},
|
486
|
+
"required": ["analysis"],
|
487
|
+
"additionalProperties": false
|
488
|
+
}
|
489
|
+
```
|
490
|
+
|
491
|
+
3. For more complex scenarios, use explicit file routing with flexible syntax options:
|
492
|
+
|
493
|
+
```bash
|
494
|
+
# Auto-naming (fastest for one-off analysis)
|
495
|
+
ostruct run analysis_template.j2 analysis_schema.json \
|
496
|
+
-fc sales_data.csv \
|
497
|
+
-fc customer_data.json \
|
498
|
+
-fs market_reports.pdf \
|
499
|
+
-ft config.yaml
|
500
|
+
|
501
|
+
# Mixed syntax with custom variable names
|
502
|
+
ostruct run analysis_template.j2 analysis_schema.json \
|
503
|
+
-fc sales_data.csv \
|
504
|
+
-fc customers customer_data.json \
|
505
|
+
--fsa reports market_reports.pdf \
|
506
|
+
--fta app_config config.yaml
|
507
|
+
|
508
|
+
# Alias syntax for reusable templates (best tab completion)
|
509
|
+
ostruct run reusable_analysis.j2 analysis_schema.json \
|
510
|
+
--fca sales_data sales_data.csv \
|
511
|
+
--fca customer_data customer_data.json \
|
512
|
+
--fsa market_reports market_reports.pdf \
|
513
|
+
--fta config config.yaml
|
514
|
+
|
515
|
+
# Code review with stable variable names
|
516
|
+
ostruct run code_review.j2 review_schema.json \
|
517
|
+
--fca source_code source_code/ \
|
518
|
+
--fsa documentation docs/ \
|
519
|
+
--fta eslint_config .eslintrc.json
|
520
|
+
```
|
521
|
+
|
522
|
+
### Example 3: Legacy Compatibility
|
523
|
+
|
524
|
+
All existing commands continue to work unchanged:
|
525
|
+
|
526
|
+
```bash
|
527
|
+
# Traditional usage (fully supported)
|
528
|
+
ostruct run extract_from_file.j2 schema.json -f text input.txt -d configs
|
529
|
+
ostruct run template.j2 schema.json -p "*.py" source -V env=prod
|
530
|
+
```
|
531
|
+
|
532
|
+
<details>
|
533
|
+
<summary><strong>System Prompt Handling</strong> (Click to expand)</summary>
|
534
|
+
|
535
|
+
ostruct-cli provides three ways to specify a system prompt, with a clear precedence order:
|
536
|
+
|
537
|
+
1. Command-line option (`--sys-prompt` or `--sys-file`):
|
538
|
+
|
539
|
+
```bash
|
540
|
+
# Direct string
|
541
|
+
ostruct run template.j2 schema.json --sys-prompt "You are an expert analyst"
|
542
|
+
|
543
|
+
# From file
|
544
|
+
ostruct run template.j2 schema.json --sys-file system_prompt.txt
|
545
|
+
```
|
546
|
+
|
547
|
+
2. Template frontmatter:
|
548
|
+
|
549
|
+
```jinja
|
550
|
+
---
|
551
|
+
system_prompt: You are an expert analyst
|
552
|
+
---
|
553
|
+
Extract information from: {{ text }}
|
554
|
+
```
|
555
|
+
|
556
|
+
3. Shared system prompts (with template frontmatter):
|
557
|
+
|
558
|
+
```jinja
|
559
|
+
---
|
560
|
+
include_system: shared/base_analyst.txt
|
561
|
+
system_prompt: Focus on financial metrics
|
562
|
+
---
|
563
|
+
Extract information from: {{ text }}
|
564
|
+
```
|
565
|
+
|
566
|
+
4. Default system prompt (built into the CLI)
|
567
|
+
|
568
|
+
### Precedence Rules
|
569
|
+
|
570
|
+
When multiple system prompts are provided, they are resolved in this order:
|
571
|
+
|
572
|
+
1. Command-line options take highest precedence:
|
573
|
+
- If both `--sys-prompt` and `--sys-file` are provided, `--sys-prompt` wins
|
574
|
+
- Use `--ignore-task-sysprompt` to ignore template frontmatter
|
575
|
+
|
576
|
+
2. Template frontmatter is used if:
|
577
|
+
- No command-line options are provided
|
578
|
+
- `--ignore-task-sysprompt` is not set
|
579
|
+
|
580
|
+
3. Default system prompt is used only if no other prompts are provided
|
581
|
+
|
582
|
+
Example combining multiple sources:
|
583
|
+
|
584
|
+
```bash
|
585
|
+
# Command-line prompt will override template frontmatter
|
586
|
+
ostruct run template.j2 schema.json --sys-prompt "Override prompt"
|
587
|
+
|
588
|
+
# Ignore template frontmatter and use default
|
589
|
+
ostruct run template.j2 schema.json --ignore-task-sysprompt
|
590
|
+
```
|
591
|
+
|
592
|
+
</details>
|
593
|
+
|
594
|
+
## Model Registry Management
|
595
|
+
|
596
|
+
ostruct-cli maintains a registry of OpenAI models and their capabilities, which includes:
|
597
|
+
|
598
|
+
- Context window sizes for each model
|
599
|
+
- Maximum output token limits
|
600
|
+
- Supported parameters and their constraints
|
601
|
+
- Model version information
|
602
|
+
|
603
|
+
To ensure you're using the latest models and features, you can update the registry:
|
604
|
+
|
605
|
+
```bash
|
606
|
+
# Update from the official repository
|
607
|
+
ostruct update-registry
|
608
|
+
|
609
|
+
# Update from a custom URL
|
610
|
+
ostruct update-registry --url https://example.com/models.yml
|
611
|
+
|
612
|
+
# Force an update even if the registry is current
|
613
|
+
ostruct update-registry --force
|
614
|
+
```
|
615
|
+
|
616
|
+
This is especially useful when:
|
617
|
+
|
618
|
+
- New OpenAI models are released
|
619
|
+
- Model capabilities or parameters change
|
620
|
+
- You need to work with custom model configurations
|
621
|
+
|
622
|
+
The registry file is stored at `~/.openai_structured/config/models.yml` and is automatically referenced when validating model parameters and token limits.
|
623
|
+
|
624
|
+
The update command uses HTTP conditional requests (If-Modified-Since headers) to check if the remote registry has changed before downloading, ensuring efficient updates.
|
625
|
+
|
626
|
+
<!--
|
627
|
+
MAINTAINER NOTE: After editing this README, please test GitHub rendering by:
|
628
|
+
1. Creating a draft PR or pushing to a test branch
|
629
|
+
2. Verifying all HTML <details> sections expand/collapse correctly
|
630
|
+
3. Checking badge display and links work as expected
|
631
|
+
4. Ensuring quickstart guide link is functional
|
632
|
+
-->
|
633
|
+
|