ostruct-cli 0.7.1__py3-none-any.whl → 0.8.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.
- ostruct/cli/__init__.py +21 -3
- ostruct/cli/base_errors.py +1 -1
- ostruct/cli/cli.py +66 -1983
- ostruct/cli/click_options.py +460 -28
- ostruct/cli/code_interpreter.py +238 -0
- ostruct/cli/commands/__init__.py +32 -0
- ostruct/cli/commands/list_models.py +128 -0
- ostruct/cli/commands/quick_ref.py +50 -0
- ostruct/cli/commands/run.py +137 -0
- ostruct/cli/commands/update_registry.py +71 -0
- ostruct/cli/config.py +277 -0
- ostruct/cli/cost_estimation.py +134 -0
- ostruct/cli/errors.py +310 -6
- ostruct/cli/exit_codes.py +1 -0
- ostruct/cli/explicit_file_processor.py +548 -0
- ostruct/cli/field_utils.py +69 -0
- ostruct/cli/file_info.py +42 -9
- ostruct/cli/file_list.py +301 -102
- ostruct/cli/file_search.py +455 -0
- ostruct/cli/file_utils.py +47 -13
- ostruct/cli/mcp_integration.py +541 -0
- ostruct/cli/model_creation.py +150 -1
- ostruct/cli/model_validation.py +204 -0
- ostruct/cli/progress_reporting.py +398 -0
- ostruct/cli/registry_updates.py +14 -9
- ostruct/cli/runner.py +1418 -0
- ostruct/cli/schema_utils.py +113 -0
- ostruct/cli/services.py +626 -0
- ostruct/cli/template_debug.py +748 -0
- ostruct/cli/template_debug_help.py +162 -0
- ostruct/cli/template_env.py +15 -6
- ostruct/cli/template_filters.py +55 -3
- ostruct/cli/template_optimizer.py +474 -0
- ostruct/cli/template_processor.py +1080 -0
- ostruct/cli/template_rendering.py +69 -34
- ostruct/cli/token_validation.py +286 -0
- ostruct/cli/types.py +78 -0
- ostruct/cli/unattended_operation.py +269 -0
- ostruct/cli/validators.py +386 -3
- {ostruct_cli-0.7.1.dist-info → ostruct_cli-0.8.0.dist-info}/LICENSE +2 -0
- ostruct_cli-0.8.0.dist-info/METADATA +633 -0
- ostruct_cli-0.8.0.dist-info/RECORD +69 -0
- {ostruct_cli-0.7.1.dist-info → ostruct_cli-0.8.0.dist-info}/WHEEL +1 -1
- ostruct_cli-0.7.1.dist-info/METADATA +0 -369
- ostruct_cli-0.7.1.dist-info/RECORD +0 -45
- {ostruct_cli-0.7.1.dist-info → ostruct_cli-0.8.0.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,113 @@
|
|
1
|
+
"""Schema utilities for ostruct CLI."""
|
2
|
+
|
3
|
+
import json
|
4
|
+
import logging
|
5
|
+
from pathlib import Path
|
6
|
+
from typing import Any, Dict, Optional
|
7
|
+
|
8
|
+
from openai_model_registry import ModelRegistry
|
9
|
+
|
10
|
+
from .errors import SchemaFileError
|
11
|
+
|
12
|
+
logger = logging.getLogger(__name__)
|
13
|
+
|
14
|
+
|
15
|
+
def make_strict(obj: Any) -> None:
|
16
|
+
"""Transform Pydantic schema for Responses API strict mode.
|
17
|
+
|
18
|
+
This function recursively adds 'additionalProperties: false' to all object types
|
19
|
+
in a JSON schema to make it compatible with OpenAI's strict mode requirement.
|
20
|
+
|
21
|
+
Args:
|
22
|
+
obj: The schema object to transform (modified in-place)
|
23
|
+
"""
|
24
|
+
if isinstance(obj, dict):
|
25
|
+
if obj.get("type") == "object" and "additionalProperties" not in obj:
|
26
|
+
obj["additionalProperties"] = False
|
27
|
+
for value in obj.values():
|
28
|
+
make_strict(value)
|
29
|
+
elif isinstance(obj, list):
|
30
|
+
for item in obj:
|
31
|
+
make_strict(item)
|
32
|
+
|
33
|
+
|
34
|
+
def supports_structured_output(model: str) -> bool:
|
35
|
+
"""Check if model supports structured output."""
|
36
|
+
try:
|
37
|
+
registry = ModelRegistry.get_instance()
|
38
|
+
capabilities = registry.get_capabilities(model)
|
39
|
+
return getattr(capabilities, "supports_structured_output", True)
|
40
|
+
except Exception:
|
41
|
+
return True
|
42
|
+
|
43
|
+
|
44
|
+
def validate_schema_file(
|
45
|
+
schema_path: str, schema_context: Optional[Dict[str, Any]] = None
|
46
|
+
) -> Dict[str, Any]:
|
47
|
+
"""Validate and load schema file.
|
48
|
+
|
49
|
+
Args:
|
50
|
+
schema_path: Path to schema file
|
51
|
+
schema_context: Optional context for error reporting
|
52
|
+
|
53
|
+
Returns:
|
54
|
+
Dict containing the loaded schema
|
55
|
+
|
56
|
+
Raises:
|
57
|
+
SchemaFileError: If schema file is invalid or cannot be read
|
58
|
+
"""
|
59
|
+
try:
|
60
|
+
with Path(schema_path).open("r") as f:
|
61
|
+
schema_data = json.load(f)
|
62
|
+
|
63
|
+
# Validate basic schema structure
|
64
|
+
if not isinstance(schema_data, dict):
|
65
|
+
raise SchemaFileError(
|
66
|
+
f"Schema file must contain a JSON object, got {type(schema_data).__name__}",
|
67
|
+
schema_path=schema_path,
|
68
|
+
context=schema_context,
|
69
|
+
)
|
70
|
+
|
71
|
+
# Must have either "schema" key or be a direct schema
|
72
|
+
if "schema" in schema_data:
|
73
|
+
# Wrapped schema format
|
74
|
+
actual_schema = schema_data["schema"]
|
75
|
+
else:
|
76
|
+
# Direct schema format
|
77
|
+
actual_schema = schema_data
|
78
|
+
|
79
|
+
if not isinstance(actual_schema, dict):
|
80
|
+
raise SchemaFileError(
|
81
|
+
f"Schema must be a JSON object, got {type(actual_schema).__name__}",
|
82
|
+
schema_path=schema_path,
|
83
|
+
context=schema_context,
|
84
|
+
)
|
85
|
+
|
86
|
+
# Validate that root type is object for structured output
|
87
|
+
if actual_schema.get("type") != "object":
|
88
|
+
raise SchemaFileError(
|
89
|
+
f"Schema root type must be 'object', got '{actual_schema.get('type')}'",
|
90
|
+
schema_path=schema_path,
|
91
|
+
context=schema_context,
|
92
|
+
)
|
93
|
+
|
94
|
+
return schema_data
|
95
|
+
|
96
|
+
except json.JSONDecodeError as e:
|
97
|
+
raise SchemaFileError(
|
98
|
+
f"Invalid JSON in schema file: {e}",
|
99
|
+
schema_path=schema_path,
|
100
|
+
context=schema_context,
|
101
|
+
) from e
|
102
|
+
except FileNotFoundError as e:
|
103
|
+
raise SchemaFileError(
|
104
|
+
f"Schema file not found: {schema_path}",
|
105
|
+
schema_path=schema_path,
|
106
|
+
context=schema_context,
|
107
|
+
) from e
|
108
|
+
except Exception as e:
|
109
|
+
raise SchemaFileError(
|
110
|
+
f"Error reading schema file: {e}",
|
111
|
+
schema_path=schema_path,
|
112
|
+
context=schema_context,
|
113
|
+
) from e
|