openai-sdk-helpers 0.6.4__tar.gz → 0.6.6__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.
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/PKG-INFO +1 -1
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/pyproject.toml +1 -1
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/agent/classifier.py +48 -4
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/base.py +100 -5
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/classification.py +49 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/.gitignore +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/LICENSE +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/README.md +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/__init__.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/agent/__init__.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/agent/base.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/agent/configuration.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/agent/coordinator.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/agent/files.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/agent/runner.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/agent/search/__init__.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/agent/search/base.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/agent/search/vector.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/agent/search/web.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/agent/summarizer.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/agent/translator.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/agent/utils.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/agent/validator.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/cli.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/enums/__init__.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/enums/base.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/environment.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/errors.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/extract/__init__.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/extract/extractor.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/extract/generator.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/files_api.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/logging.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/prompt/__init__.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/prompt/base.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/prompt/classifier.jinja +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/prompt/extractor_config_agent_instructions.jinja +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/prompt/extractor_config_generator.jinja +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/prompt/extractor_config_generator_instructions.jinja +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/prompt/extractor_prompt_optimizer_agent_instructions.jinja +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/prompt/extractor_prompt_optimizer_request.jinja +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/prompt/summarizer.jinja +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/prompt/translator.jinja +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/prompt/validator.jinja +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/prompt/vector_planner.jinja +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/prompt/vector_search.jinja +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/prompt/vector_writer.jinja +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/py.typed +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/response/__init__.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/response/base.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/response/configuration.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/response/files.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/response/messages.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/response/planner.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/response/prompter.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/response/runner.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/response/tool_call.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/response/vector_store.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/settings.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/streamlit_app/__init__.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/streamlit_app/app.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/streamlit_app/configuration.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/__init__.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/agent_blueprint.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/extraction.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/plan/__init__.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/plan/enum.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/plan/helpers.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/plan/plan.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/plan/task.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/plan/types.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/prompt.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/responses.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/summary.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/translation.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/validation.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/vector_search.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/web_search.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/tools.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/types.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/utils/__init__.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/utils/async_utils.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/utils/coercion.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/utils/encoding.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/utils/instructions.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/utils/json/__init__.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/utils/json/base_model.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/utils/json/data_class.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/utils/json/ref.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/utils/json/utils.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/utils/langextract.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/utils/output_validation.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/utils/path_utils.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/utils/registry.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/utils/validation.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/vector_storage/__init__.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/vector_storage/cleanup.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/vector_storage/storage.py +0 -0
- {openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/vector_storage/types.py +0 -0
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/agent/classifier.py
RENAMED
|
@@ -26,6 +26,8 @@ from ..utils import ensure_list
|
|
|
26
26
|
from .base import AgentBase
|
|
27
27
|
from .configuration import AgentConfiguration
|
|
28
28
|
|
|
29
|
+
_CONTINUE_CONFIDENCE_THRESHOLD = 0.7
|
|
30
|
+
|
|
29
31
|
|
|
30
32
|
class TaxonomyClassifierAgent(AgentBase):
|
|
31
33
|
"""Classify text by recursively traversing a taxonomy.
|
|
@@ -394,6 +396,13 @@ class TaxonomyClassifierAgent(AgentBase):
|
|
|
394
396
|
|
|
395
397
|
resolved_nodes = _resolve_nodes(node_paths, step)
|
|
396
398
|
|
|
399
|
+
should_continue = _should_continue_from_stop(step, resolved_nodes)
|
|
400
|
+
if should_continue:
|
|
401
|
+
step = step.model_copy(
|
|
402
|
+
update={"stop_reason": ClassificationStopReason.CONTINUE}
|
|
403
|
+
)
|
|
404
|
+
state.steps[-1] = step
|
|
405
|
+
|
|
397
406
|
if step.stop_reason.is_terminal:
|
|
398
407
|
if resolved_nodes:
|
|
399
408
|
state.final_nodes.extend(resolved_nodes)
|
|
@@ -407,7 +416,7 @@ class TaxonomyClassifierAgent(AgentBase):
|
|
|
407
416
|
return
|
|
408
417
|
|
|
409
418
|
base_steps_len = len(state.steps)
|
|
410
|
-
child_tasks: list[tuple[Awaitable["_TraversalState"], int]] = []
|
|
419
|
+
child_tasks: list[tuple[Awaitable["_TraversalState"], int, TaxonomyNode]] = []
|
|
411
420
|
for node in resolved_nodes:
|
|
412
421
|
if node.children:
|
|
413
422
|
sub_agent = self._build_sub_agent(list(node.children))
|
|
@@ -429,6 +438,7 @@ class TaxonomyClassifierAgent(AgentBase):
|
|
|
429
438
|
state=sub_state,
|
|
430
439
|
),
|
|
431
440
|
base_final_nodes_len,
|
|
441
|
+
node,
|
|
432
442
|
)
|
|
433
443
|
)
|
|
434
444
|
else:
|
|
@@ -439,13 +449,19 @@ class TaxonomyClassifierAgent(AgentBase):
|
|
|
439
449
|
)
|
|
440
450
|
if child_tasks:
|
|
441
451
|
child_states = await asyncio.gather(
|
|
442
|
-
*(child_task for child_task, _ in child_tasks)
|
|
452
|
+
*(child_task for child_task, _, _ in child_tasks)
|
|
443
453
|
)
|
|
444
|
-
for child_state, (_, base_final_nodes_len) in zip(
|
|
454
|
+
for child_state, (_, base_final_nodes_len, parent_node) in zip(
|
|
445
455
|
child_states, child_tasks, strict=True
|
|
446
456
|
):
|
|
447
457
|
state.steps.extend(child_state.steps[base_steps_len:])
|
|
448
|
-
|
|
458
|
+
child_final_nodes = child_state.final_nodes[base_final_nodes_len:]
|
|
459
|
+
state.final_nodes.extend(child_final_nodes)
|
|
460
|
+
if should_continue and not child_final_nodes:
|
|
461
|
+
state.final_nodes.append(parent_node)
|
|
462
|
+
state.best_confidence = _max_confidence(
|
|
463
|
+
state.best_confidence, step.confidence
|
|
464
|
+
)
|
|
449
465
|
state.best_confidence = _max_confidence(
|
|
450
466
|
state.best_confidence, child_state.best_confidence
|
|
451
467
|
)
|
|
@@ -627,6 +643,34 @@ def _resolve_stop_reason(state: _TraversalState) -> ClassificationStopReason:
|
|
|
627
643
|
return ClassificationStopReason.NO_MATCH
|
|
628
644
|
|
|
629
645
|
|
|
646
|
+
def _should_continue_from_stop(
|
|
647
|
+
step: ClassificationStep,
|
|
648
|
+
resolved_nodes: Sequence[TaxonomyNode],
|
|
649
|
+
threshold: float = _CONTINUE_CONFIDENCE_THRESHOLD,
|
|
650
|
+
) -> bool:
|
|
651
|
+
"""Return True when a stop reason should continue traversal.
|
|
652
|
+
|
|
653
|
+
Parameters
|
|
654
|
+
----------
|
|
655
|
+
step : ClassificationStep
|
|
656
|
+
Classification step to evaluate.
|
|
657
|
+
resolved_nodes : Sequence[TaxonomyNode]
|
|
658
|
+
Resolved taxonomy nodes from the classification step.
|
|
659
|
+
threshold : float, default=0.7
|
|
660
|
+
Confidence threshold for overriding a stop reason.
|
|
661
|
+
|
|
662
|
+
Returns
|
|
663
|
+
-------
|
|
664
|
+
bool
|
|
665
|
+
True when traversal should proceed despite a stop reason.
|
|
666
|
+
"""
|
|
667
|
+
if step.stop_reason is not ClassificationStopReason.STOP:
|
|
668
|
+
return False
|
|
669
|
+
if step.confidence is None or step.confidence < threshold:
|
|
670
|
+
return False
|
|
671
|
+
return any(node.children for node in resolved_nodes)
|
|
672
|
+
|
|
673
|
+
|
|
630
674
|
def _normalize_roots(
|
|
631
675
|
taxonomy: TaxonomyNode | Sequence[TaxonomyNode],
|
|
632
676
|
) -> list[TaxonomyNode]:
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/base.py
RENAMED
|
@@ -174,6 +174,100 @@ def _ensure_schema_has_type(schema: dict[str, Any]) -> None:
|
|
|
174
174
|
schema.update(_build_any_value_schema())
|
|
175
175
|
|
|
176
176
|
|
|
177
|
+
def _strip_ref_types(
|
|
178
|
+
schema: dict[str, Any],
|
|
179
|
+
*,
|
|
180
|
+
nullable_fields: set[str] | None = None,
|
|
181
|
+
) -> None:
|
|
182
|
+
"""Remove type entries from enum $ref nodes when non-nullable.
|
|
183
|
+
|
|
184
|
+
Parameters
|
|
185
|
+
----------
|
|
186
|
+
schema : dict[str, Any]
|
|
187
|
+
Root schema to clean in place.
|
|
188
|
+
nullable_fields : set[str] | None, optional
|
|
189
|
+
Field names that should remain nullable. Defaults to None.
|
|
190
|
+
"""
|
|
191
|
+
field_names = nullable_fields or set()
|
|
192
|
+
|
|
193
|
+
def _resolve_ref(ref: str) -> dict[str, Any] | None:
|
|
194
|
+
if not ref.startswith("#/"):
|
|
195
|
+
return None
|
|
196
|
+
pointer = ref.removeprefix("#/")
|
|
197
|
+
current: Any = schema
|
|
198
|
+
for part in pointer.split("/"):
|
|
199
|
+
if not isinstance(current, dict):
|
|
200
|
+
return None
|
|
201
|
+
current = current.get(part)
|
|
202
|
+
if isinstance(current, dict):
|
|
203
|
+
return current
|
|
204
|
+
return None
|
|
205
|
+
|
|
206
|
+
def _is_enum_ref(ref: str) -> bool:
|
|
207
|
+
ref_target = _resolve_ref(ref)
|
|
208
|
+
if not isinstance(ref_target, dict):
|
|
209
|
+
return False
|
|
210
|
+
return "enum" in ref_target
|
|
211
|
+
|
|
212
|
+
def _is_null_schema(entry: Any) -> bool:
|
|
213
|
+
if not isinstance(entry, dict):
|
|
214
|
+
return False
|
|
215
|
+
entry_type = entry.get("type")
|
|
216
|
+
if entry_type == "null":
|
|
217
|
+
return True
|
|
218
|
+
if isinstance(entry_type, list) and "null" in entry_type:
|
|
219
|
+
return True
|
|
220
|
+
return False
|
|
221
|
+
|
|
222
|
+
def _walk(
|
|
223
|
+
node: Any,
|
|
224
|
+
*,
|
|
225
|
+
nullable_context: bool = False,
|
|
226
|
+
nullable_property: bool = False,
|
|
227
|
+
) -> None:
|
|
228
|
+
if isinstance(node, dict):
|
|
229
|
+
ref = node.get("$ref")
|
|
230
|
+
if (
|
|
231
|
+
isinstance(ref, str)
|
|
232
|
+
and _is_enum_ref(ref)
|
|
233
|
+
and not nullable_context
|
|
234
|
+
and not nullable_property
|
|
235
|
+
):
|
|
236
|
+
node.pop("type", None)
|
|
237
|
+
for key, value in node.items():
|
|
238
|
+
if key == "anyOf" and isinstance(value, list):
|
|
239
|
+
anyof_nullable = any(_is_null_schema(entry) for entry in value)
|
|
240
|
+
for entry in value:
|
|
241
|
+
_walk(
|
|
242
|
+
entry,
|
|
243
|
+
nullable_context=anyof_nullable or nullable_context,
|
|
244
|
+
nullable_property=nullable_property,
|
|
245
|
+
)
|
|
246
|
+
continue
|
|
247
|
+
if key == "properties" and isinstance(value, dict):
|
|
248
|
+
for prop_name, prop_schema in value.items():
|
|
249
|
+
_walk(
|
|
250
|
+
prop_schema,
|
|
251
|
+
nullable_context=nullable_context,
|
|
252
|
+
nullable_property=prop_name in field_names,
|
|
253
|
+
)
|
|
254
|
+
continue
|
|
255
|
+
_walk(
|
|
256
|
+
value,
|
|
257
|
+
nullable_context=nullable_context,
|
|
258
|
+
nullable_property=nullable_property,
|
|
259
|
+
)
|
|
260
|
+
elif isinstance(node, list):
|
|
261
|
+
for item in node:
|
|
262
|
+
_walk(
|
|
263
|
+
item,
|
|
264
|
+
nullable_context=nullable_context,
|
|
265
|
+
nullable_property=nullable_property,
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
_walk(schema)
|
|
269
|
+
|
|
270
|
+
|
|
177
271
|
def _hydrate_ref_types(schema: dict[str, Any]) -> None:
|
|
178
272
|
"""Attach explicit types to $ref nodes when available.
|
|
179
273
|
|
|
@@ -556,17 +650,18 @@ class StructureBase(BaseModelJSONSerializable):
|
|
|
556
650
|
|
|
557
651
|
cleaned_schema = cast(dict[str, Any], clean_refs(schema))
|
|
558
652
|
|
|
559
|
-
cleaned_schema = cast(dict[str, Any], cleaned_schema)
|
|
560
|
-
_hydrate_ref_types(cleaned_schema)
|
|
561
|
-
_ensure_items_have_schema(cleaned_schema)
|
|
562
|
-
_ensure_schema_has_type(cleaned_schema)
|
|
563
|
-
|
|
564
653
|
nullable_fields = {
|
|
565
654
|
name
|
|
566
655
|
for name, model_field in getattr(cls, "model_fields", {}).items()
|
|
567
656
|
if getattr(model_field, "default", inspect.Signature.empty) is None
|
|
568
657
|
}
|
|
569
658
|
|
|
659
|
+
cleaned_schema = cast(dict[str, Any], cleaned_schema)
|
|
660
|
+
_hydrate_ref_types(cleaned_schema)
|
|
661
|
+
_ensure_items_have_schema(cleaned_schema)
|
|
662
|
+
_ensure_schema_has_type(cleaned_schema)
|
|
663
|
+
_strip_ref_types(cleaned_schema, nullable_fields=nullable_fields)
|
|
664
|
+
|
|
570
665
|
properties = cleaned_schema.get("properties", {})
|
|
571
666
|
if isinstance(properties, dict) and nullable_fields:
|
|
572
667
|
for field_name in nullable_fields:
|
|
@@ -480,6 +480,8 @@ class ClassificationResult(StructureBase):
|
|
|
480
480
|
Yield selected identifiers across all steps.
|
|
481
481
|
selected_nodes
|
|
482
482
|
Return the selected identifiers across all steps.
|
|
483
|
+
to_lightweight_summary
|
|
484
|
+
Return a lightweight summary of selected node paths.
|
|
483
485
|
|
|
484
486
|
Examples
|
|
485
487
|
--------
|
|
@@ -565,6 +567,52 @@ class ClassificationResult(StructureBase):
|
|
|
565
567
|
if normalized:
|
|
566
568
|
yield normalized
|
|
567
569
|
|
|
570
|
+
def to_lightweight_summary(self) -> "ClassificationSummary | None":
|
|
571
|
+
"""Return a lightweight summary of selected node paths.
|
|
572
|
+
|
|
573
|
+
Returns
|
|
574
|
+
-------
|
|
575
|
+
ClassificationSummary or None
|
|
576
|
+
Summary containing the ``full_paths`` of selected nodes, or None
|
|
577
|
+
when no selections exist.
|
|
578
|
+
|
|
579
|
+
Examples
|
|
580
|
+
--------
|
|
581
|
+
>>> result = ClassificationResult(steps=[])
|
|
582
|
+
>>> result.to_lightweight_summary() is None
|
|
583
|
+
True
|
|
584
|
+
"""
|
|
585
|
+
full_paths = [
|
|
586
|
+
format_path_identifier(taxonomy_enum_path(node))
|
|
587
|
+
for node in self.selected_nodes
|
|
588
|
+
]
|
|
589
|
+
if not full_paths:
|
|
590
|
+
return None
|
|
591
|
+
return ClassificationSummary(full_paths=full_paths)
|
|
592
|
+
|
|
593
|
+
|
|
594
|
+
class ClassificationSummary(StructureBase):
|
|
595
|
+
"""Represent a lightweight summary of selected taxonomy paths.
|
|
596
|
+
|
|
597
|
+
Attributes
|
|
598
|
+
----------
|
|
599
|
+
full_paths : list[str] or None
|
|
600
|
+
Selected taxonomy paths including parent segments.
|
|
601
|
+
|
|
602
|
+
Methods
|
|
603
|
+
-------
|
|
604
|
+
to_json()
|
|
605
|
+
Serialize the summary to a JSON-compatible dictionary.
|
|
606
|
+
from_json(data)
|
|
607
|
+
Construct a summary instance from JSON-compatible data.
|
|
608
|
+
"""
|
|
609
|
+
|
|
610
|
+
full_paths: list[str] | None = spec_field(
|
|
611
|
+
"full_paths",
|
|
612
|
+
description="Selected taxonomy paths including parent segments.",
|
|
613
|
+
default=None,
|
|
614
|
+
)
|
|
615
|
+
|
|
568
616
|
|
|
569
617
|
def taxonomy_enum_path(value: Enum | str | None) -> list[str]:
|
|
570
618
|
"""Return the taxonomy path segments for an enum value.
|
|
@@ -598,6 +646,7 @@ def taxonomy_enum_path(value: Enum | str | None) -> list[str]:
|
|
|
598
646
|
|
|
599
647
|
__all__ = [
|
|
600
648
|
"ClassificationResult",
|
|
649
|
+
"ClassificationSummary",
|
|
601
650
|
"ClassificationStep",
|
|
602
651
|
"ClassificationStopReason",
|
|
603
652
|
"Taxonomy",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/agent/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/agent/configuration.py
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/agent/coordinator.py
RENAMED
|
File without changes
|
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/agent/runner.py
RENAMED
|
File without changes
|
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/agent/search/base.py
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/agent/search/vector.py
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/agent/search/web.py
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/agent/summarizer.py
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/agent/translator.py
RENAMED
|
File without changes
|
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/agent/validator.py
RENAMED
|
File without changes
|
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/enums/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/extract/__init__.py
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/extract/extractor.py
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/extract/generator.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/prompt/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/prompt/classifier.jinja
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/prompt/summarizer.jinja
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/prompt/translator.jinja
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/prompt/validator.jinja
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/response/__init__.py
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/response/base.py
RENAMED
|
File without changes
|
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/response/files.py
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/response/messages.py
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/response/planner.py
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/response/prompter.py
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/response/runner.py
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/response/tool_call.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/streamlit_app/app.py
RENAMED
|
File without changes
|
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/extraction.py
RENAMED
|
File without changes
|
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/plan/enum.py
RENAMED
|
File without changes
|
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/plan/plan.py
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/plan/task.py
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/plan/types.py
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/prompt.py
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/responses.py
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/summary.py
RENAMED
|
File without changes
|
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/validation.py
RENAMED
|
File without changes
|
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/structure/web_search.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/utils/__init__.py
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/utils/async_utils.py
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/utils/coercion.py
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/utils/encoding.py
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/utils/instructions.py
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/utils/json/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/utils/json/ref.py
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/utils/json/utils.py
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/utils/langextract.py
RENAMED
|
File without changes
|
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/utils/path_utils.py
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/utils/registry.py
RENAMED
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/utils/validation.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openai_sdk_helpers-0.6.4 → openai_sdk_helpers-0.6.6}/src/openai_sdk_helpers/vector_storage/types.py
RENAMED
|
File without changes
|