openai-sdk-helpers 0.4.2__py3-none-any.whl → 0.5.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.
Files changed (68) hide show
  1. openai_sdk_helpers/__init__.py +45 -41
  2. openai_sdk_helpers/agent/__init__.py +4 -6
  3. openai_sdk_helpers/agent/base.py +110 -191
  4. openai_sdk_helpers/agent/{config.py → configuration.py} +24 -32
  5. openai_sdk_helpers/agent/{coordination.py → coordinator.py} +22 -23
  6. openai_sdk_helpers/agent/runner.py +3 -45
  7. openai_sdk_helpers/agent/search/base.py +54 -76
  8. openai_sdk_helpers/agent/search/vector.py +92 -108
  9. openai_sdk_helpers/agent/search/web.py +104 -82
  10. openai_sdk_helpers/agent/summarizer.py +22 -28
  11. openai_sdk_helpers/agent/translator.py +22 -24
  12. openai_sdk_helpers/agent/{validation.py → validator.py} +19 -23
  13. openai_sdk_helpers/cli.py +8 -22
  14. openai_sdk_helpers/environment.py +8 -13
  15. openai_sdk_helpers/errors.py +9 -0
  16. openai_sdk_helpers/extract/__init__.py +23 -0
  17. openai_sdk_helpers/extract/extractor.py +157 -0
  18. openai_sdk_helpers/extract/generator.py +476 -0
  19. openai_sdk_helpers/prompt/extractor_config_agent_instructions.jinja +6 -0
  20. openai_sdk_helpers/prompt/extractor_config_generator.jinja +37 -0
  21. openai_sdk_helpers/prompt/extractor_config_generator_instructions.jinja +9 -0
  22. openai_sdk_helpers/prompt/extractor_prompt_optimizer_agent_instructions.jinja +4 -0
  23. openai_sdk_helpers/prompt/extractor_prompt_optimizer_request.jinja +11 -0
  24. openai_sdk_helpers/prompt/vector_planner.jinja +7 -0
  25. openai_sdk_helpers/prompt/vector_search.jinja +6 -0
  26. openai_sdk_helpers/prompt/vector_writer.jinja +7 -0
  27. openai_sdk_helpers/response/__init__.py +3 -7
  28. openai_sdk_helpers/response/base.py +89 -98
  29. openai_sdk_helpers/response/{config.py → configuration.py} +45 -20
  30. openai_sdk_helpers/response/files.py +2 -0
  31. openai_sdk_helpers/response/planner.py +1 -1
  32. openai_sdk_helpers/response/prompter.py +1 -1
  33. openai_sdk_helpers/response/runner.py +1 -48
  34. openai_sdk_helpers/response/tool_call.py +0 -141
  35. openai_sdk_helpers/response/vector_store.py +8 -5
  36. openai_sdk_helpers/streamlit_app/__init__.py +1 -1
  37. openai_sdk_helpers/streamlit_app/app.py +17 -18
  38. openai_sdk_helpers/streamlit_app/{config.py → configuration.py} +13 -13
  39. openai_sdk_helpers/structure/__init__.py +16 -0
  40. openai_sdk_helpers/structure/base.py +239 -278
  41. openai_sdk_helpers/structure/extraction.py +1228 -0
  42. openai_sdk_helpers/structure/plan/plan.py +0 -20
  43. openai_sdk_helpers/structure/plan/task.py +0 -33
  44. openai_sdk_helpers/structure/prompt.py +16 -0
  45. openai_sdk_helpers/structure/responses.py +2 -2
  46. openai_sdk_helpers/structure/web_search.py +0 -10
  47. openai_sdk_helpers/tools.py +346 -99
  48. openai_sdk_helpers/types.py +3 -3
  49. openai_sdk_helpers/utils/__init__.py +9 -6
  50. openai_sdk_helpers/utils/json/base_model.py +316 -33
  51. openai_sdk_helpers/utils/json/data_class.py +1 -1
  52. openai_sdk_helpers/utils/langextract.py +194 -0
  53. openai_sdk_helpers/utils/registry.py +19 -15
  54. openai_sdk_helpers/vector_storage/storage.py +1 -1
  55. {openai_sdk_helpers-0.4.2.dist-info → openai_sdk_helpers-0.5.0.dist-info}/METADATA +25 -11
  56. openai_sdk_helpers-0.5.0.dist-info/RECORD +95 -0
  57. openai_sdk_helpers/agent/prompt_utils.py +0 -15
  58. openai_sdk_helpers/context_manager.py +0 -241
  59. openai_sdk_helpers/deprecation.py +0 -167
  60. openai_sdk_helpers/retry.py +0 -175
  61. openai_sdk_helpers/streamlit_app/streamlit_web_search.py +0 -75
  62. openai_sdk_helpers/utils/deprecation.py +0 -167
  63. openai_sdk_helpers-0.4.2.dist-info/RECORD +0 -88
  64. /openai_sdk_helpers/{logging_config.py → logging.py} +0 -0
  65. /openai_sdk_helpers/{config.py → settings.py} +0 -0
  66. {openai_sdk_helpers-0.4.2.dist-info → openai_sdk_helpers-0.5.0.dist-info}/WHEEL +0 -0
  67. {openai_sdk_helpers-0.4.2.dist-info → openai_sdk_helpers-0.5.0.dist-info}/entry_points.txt +0 -0
  68. {openai_sdk_helpers-0.4.2.dist-info → openai_sdk_helpers-0.5.0.dist-info}/licenses/LICENSE +0 -0
@@ -4,13 +4,17 @@ from __future__ import annotations
4
4
 
5
5
  import warnings
6
6
  from pathlib import Path
7
- from typing import Generic, Protocol, TypeVar
8
- from typing_extensions import Self
7
+ from typing import Generic, TypeVar
8
+ from typing import Protocol
9
9
 
10
+ try:
11
+ from typing import Self # Python 3.11+
12
+ except ImportError:
13
+ from typing_extensions import Self # type: ignore[no-redef]
10
14
  from .path_utils import ensure_directory
11
15
 
12
16
 
13
- class RegistrySerializable(Protocol):
17
+ class RegistryProtocol(Protocol):
14
18
  """Protocol describing serializable registry entries.
15
19
 
16
20
  Methods
@@ -31,12 +35,12 @@ class RegistrySerializable(Protocol):
31
35
  ...
32
36
 
33
37
  @classmethod
34
- def from_json_file(cls, filepath: Path | str) -> Self:
38
+ def from_json_file(cls, filepath: Path | str) -> "Self":
35
39
  """Load an instance from a JSON file."""
36
40
  ...
37
41
 
38
42
 
39
- T = TypeVar("T", bound=RegistrySerializable)
43
+ T = TypeVar("T", bound=RegistryProtocol)
40
44
 
41
45
 
42
46
  class RegistryBase(Generic[T]):
@@ -53,7 +57,7 @@ class RegistryBase(Generic[T]):
53
57
 
54
58
  Methods
55
59
  -------
56
- register(config)
60
+ register(configuration)
57
61
  Add a configuration to the registry.
58
62
  get(name)
59
63
  Retrieve a configuration by name.
@@ -82,12 +86,12 @@ class RegistryBase(Generic[T]):
82
86
  """
83
87
  return self._configs
84
88
 
85
- def register(self, config: T) -> None:
89
+ def register(self, configuration: T) -> None:
86
90
  """Add a configuration to the registry.
87
91
 
88
92
  Parameters
89
93
  ----------
90
- config : T
94
+ configuration : T
91
95
  Configuration to register. Must have a 'name' attribute.
92
96
 
93
97
  Raises
@@ -95,13 +99,13 @@ class RegistryBase(Generic[T]):
95
99
  ValueError
96
100
  If a configuration with the same name is already registered.
97
101
  """
98
- name = getattr(config, "name")
102
+ name = getattr(configuration, "name")
99
103
  if name in self._configs:
100
104
  raise ValueError(
101
105
  f"Configuration '{name}' is already registered. "
102
106
  "Use a unique name or clear the registry first."
103
107
  )
104
- self._configs[name] = config
108
+ self._configs[name] = configuration
105
109
 
106
110
  def get(self, name: str) -> T:
107
111
  """Retrieve a configuration by name.
@@ -166,10 +170,10 @@ class RegistryBase(Generic[T]):
166
170
  return
167
171
 
168
172
  for config_name in config_names:
169
- config = self.get(config_name)
173
+ configuration = self.get(config_name)
170
174
  filename = f"{config_name}.json"
171
- filepath = dir_path / config.__class__.__name__ / filename
172
- config.to_json_file(filepath)
175
+ filepath = dir_path / configuration.__class__.__name__ / filename
176
+ configuration.to_json_file(filepath)
173
177
 
174
178
  def load_from_directory(self, path: Path | str, *, config_class: type[T]) -> int:
175
179
  """Load all configurations from JSON files in a directory.
@@ -208,8 +212,8 @@ class RegistryBase(Generic[T]):
208
212
  count = 0
209
213
  for json_file in sorted(dir_path.glob("*.json")):
210
214
  try:
211
- config = config_class.from_json_file(json_file)
212
- self.register(config)
215
+ configuration = config_class.from_json_file(json_file)
216
+ self.register(configuration)
213
217
  count += 1
214
218
  except Exception as exc:
215
219
  # Log warning but continue processing other files
@@ -21,7 +21,7 @@ from openai.types.vector_store import VectorStore
21
21
  from openai.types.vector_store_search_response import VectorStoreSearchResponse
22
22
  from tqdm import tqdm
23
23
 
24
- from ..config import OpenAISettings
24
+ from ..settings import OpenAISettings
25
25
  from ..errors import ConfigurationError, VectorStorageError
26
26
  from ..types import OpenAIClient
27
27
  from ..utils import ensure_list, ensure_directory, log
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openai-sdk-helpers
3
- Version: 0.4.2
3
+ Version: 0.5.0
4
4
  Summary: Composable helpers for OpenAI SDK agents, prompts, and storage
5
5
  Author: openai-sdk-helpers maintainers
6
6
  License: MIT
@@ -17,6 +17,7 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
17
  Classifier: Typing :: Typed
18
18
  Requires-Python: >=3.10
19
19
  Requires-Dist: jinja2
20
+ Requires-Dist: langextract
20
21
  Requires-Dist: openai-agents<1.0.0,>=0.6.4
21
22
  Requires-Dist: openai<3.0.0,>=2.14.0
22
23
  Requires-Dist: pydantic<3,>=2.7
@@ -31,6 +32,8 @@ Requires-Dist: pyright; extra == 'dev'
31
32
  Requires-Dist: pytest; extra == 'dev'
32
33
  Requires-Dist: pytest-asyncio; extra == 'dev'
33
34
  Requires-Dist: pytest-cov; extra == 'dev'
35
+ Provides-Extra: extract
36
+ Requires-Dist: langextract; extra == 'extract'
34
37
  Description-Content-Type: text/markdown
35
38
 
36
39
  <div align="center">
@@ -78,7 +81,7 @@ structures, configuration helpers, and orchestration utilities—while leaving
78
81
  application-specific prompts and tools to the consuming project.
79
82
 
80
83
  **Important**: This library integrates with **two distinct OpenAI SDKs**:
81
- - **`openai-agents`** - Used by the `agent` module for high-level agent workflows with automatic tool handling and streaming
84
+ - **`openai-agents`** - Used by the `agent` module for high-level agent workflows with automatic tool handling
82
85
  - **`openai`** - Used by the `response` module for direct API interactions with fine-grained control over responses
83
86
 
84
87
  The `agent` module provides a higher-level abstraction for building agents, while the `response` module offers lower-level control for custom response handling workflows.
@@ -193,10 +196,11 @@ report = vector_search.run_agent_sync("Explain quantum entanglement for beginner
193
196
  print(report.report)
194
197
  ```
195
198
 
196
- **Note**: The vector search workflow requires prompt templates for each agent
197
- (`vector_planner.jinja`, `vector_search.jinja`, and `vector_writer.jinja`).
198
- If your `prompt_dir` doesn't contain these files, agent construction will fail
199
- with a `FileNotFoundError`.
199
+ **Note**: The vector search workflow ships with default prompt templates
200
+ (`vector_planner.jinja`, `vector_search.jinja`, and `vector_writer.jinja`).
201
+ You only need to pass a `prompt_dir` when you want to override them; if the
202
+ directory you supply is missing any of the templates, agent construction will
203
+ fail with a `FileNotFoundError`.
200
204
 
201
205
  ### Text utilities
202
206
 
@@ -301,7 +305,7 @@ response.close()
301
305
  ```
302
306
 
303
307
  **Key Differences:**
304
- - **Agent Module**: Higher-level abstraction with built-in streaming, automatic tool handling, and agent-specific workflows
308
+ - **Agent Module**: Higher-level abstraction with automatic tool handling and agent-specific workflows
305
309
  - **Response Module**: Lower-level control with manual message management, custom tool handlers, and direct API access
306
310
 
307
311
  ## Advanced Usage
@@ -510,7 +514,7 @@ src/openai_sdk_helpers/
510
514
  │ ├── summary.py # Summary output structures
511
515
  │ └── validation.py # Validation result structures
512
516
  ├── vector_storage/ # Vector store abstraction layer
513
- ├── config.py # OpenAI settings and configuration
517
+ ├── configuration.py # OpenAI settings and configuration
514
518
  └── utils/ # JSON serialization, logging, and helpers
515
519
 
516
520
  tests/ # Comprehensive unit test suite
@@ -522,7 +526,7 @@ The package is organized around cohesive, reusable building blocks:
522
526
 
523
527
  ### Agent Modules (Built on `openai-agents` SDK)
524
528
 
525
- These modules use the `openai-agents` SDK for high-level agent workflows with automatic streaming, tool handling, and conversation management.
529
+ These modules use the `openai-agents` SDK for high-level agent workflows with automatic tool handling and conversation management.
526
530
 
527
531
  - **`openai_sdk_helpers.agent.base.AgentBase`**
528
532
  Base class for all agents with synchronous and asynchronous execution support.
@@ -562,7 +566,7 @@ These modules use the standard `openai` SDK for direct API interactions with fin
562
566
 
563
567
  ### Configuration and Data Structures (Shared)
564
568
 
565
- - **`openai_sdk_helpers.config.OpenAISettings`**
569
+ - **`openai_sdk_helpers.settings.OpenAISettings`**
566
570
  Centralizes OpenAI API configuration with environment variable support.
567
571
  Creates configured OpenAI clients with consistent settings.
568
572
 
@@ -584,6 +588,17 @@ These modules use the standard `openai` SDK for direct API interactions with fin
584
588
  - **`openai_sdk_helpers.utils`**
585
589
  JSON serialization helpers, logging utilities, and common validation functions.
586
590
 
591
+ - **`openai_sdk_helpers.utils.langextract`**
592
+ Adapter helpers for running LangExtract-style extractors and validating the
593
+ results into Pydantic models.
594
+
595
+ ## Related Projects
596
+
597
+ - **[LangExtract](https://github.com/google/langextract)**
598
+ Google-maintained toolkit for extracting structured data from language model
599
+ outputs, which can complement the validation and response utilities in
600
+ `openai-sdk-helpers`.
601
+
587
602
  ## Contributing
588
603
 
589
604
  Contributions are welcome! We appreciate functional changes accompanied by
@@ -696,4 +711,3 @@ recognizing types:
696
711
  - Check the [Key Modules](#key-modules) section for API documentation
697
712
  - Review examples in the [Quickstart](#quickstart) and [Advanced Usage](#advanced-usage) sections
698
713
  - Open an issue on GitHub for bugs or feature requests
699
-
@@ -0,0 +1,95 @@
1
+ openai_sdk_helpers/__init__.py,sha256=8I469KuzrbAjhNX2A5UnYt_kSmjXqQbfHectTeUx7TI,5163
2
+ openai_sdk_helpers/cli.py,sha256=BDc08NqWVfL4GBekxMfN5IPPB4pmN1Od9sVpKtIJRZk,8025
3
+ openai_sdk_helpers/environment.py,sha256=mNoswzIdv37tTRhFwA2B6_Onxsm7vhfjPArfwhYuL7g,1825
4
+ openai_sdk_helpers/errors.py,sha256=ZclLp94o08fSsFNjFn_yrX9yTjw1RE0v7A5T1hBChUc,2925
5
+ openai_sdk_helpers/files_api.py,sha256=uMKHvGg1Od0J95Izl3AG9ofQYq8EDJXEty7zP0oKjJM,12569
6
+ openai_sdk_helpers/logging.py,sha256=JcR0FTWht1tYdwD-bXH835pr0JV0RwHfY3poruiZGHM,795
7
+ openai_sdk_helpers/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ openai_sdk_helpers/settings.py,sha256=xK_u0YNKgtPrLrZrVr4F4k0CvSuYbsmkqqw9mCMdyF8,10932
9
+ openai_sdk_helpers/tools.py,sha256=8hhcytpmDfoXV16UQbDmDVV0rhLOn8c_VjXO8XaTFLQ,19000
10
+ openai_sdk_helpers/types.py,sha256=ejCG0rYqJhjOQvKLoNnzq-TzcKCFt69GVfi7y805NkU,1451
11
+ openai_sdk_helpers/agent/__init__.py,sha256=SRz8WupyS89c7sYML2hkwZLkIu6zczyI9MVyDWAHK1w,1040
12
+ openai_sdk_helpers/agent/base.py,sha256=y2LEkg4AVqNZQ_OPAn5yTy4x8lREq8tJPaUwAYTNHQY,24065
13
+ openai_sdk_helpers/agent/configuration.py,sha256=FU3xnb8-8qoezLW47WwxZg7z2AxNXRW1Svl0FMsk8kc,14244
14
+ openai_sdk_helpers/agent/coordinator.py,sha256=lVjA0yI-GhGKlqbNR_k9GOCrUjFoZ0QoqRaafHckyME,18052
15
+ openai_sdk_helpers/agent/runner.py,sha256=l2NPS9VA9d4RISuBfanFfKxXNYSHQ7MTjRsuzx4APls,3473
16
+ openai_sdk_helpers/agent/summarizer.py,sha256=-yVm-KdTvGRXGj1MlEikTAFYVlPoovLNIL3Tc_WYIzs,3653
17
+ openai_sdk_helpers/agent/translator.py,sha256=6Gj1cqT-W5j32F14sY9kOCFQenq_odceu2fi8hud_Z0,5970
18
+ openai_sdk_helpers/agent/utils.py,sha256=DTD5foCqGYfXf13F2bZMYIQROl7SbDSy5GDPGi0Zl-0,1089
19
+ openai_sdk_helpers/agent/validator.py,sha256=krktzjaHhEprn76F7hD4cH6H2CwucmFN1KWJ_vjl01g,4774
20
+ openai_sdk_helpers/agent/search/__init__.py,sha256=LXXzEcX2MU7_htHRdRCGPw0hsr9CrZn0ESii7GZJMBw,806
21
+ openai_sdk_helpers/agent/search/base.py,sha256=BonbNL7yAQyImhPTrsxZs5axLmaTbwjVGdADNYQaEvY,9764
22
+ openai_sdk_helpers/agent/search/vector.py,sha256=7GoDwvarwyIJIYlP-JpMyH1XokInNalRUJT0HNdQMBk,14130
23
+ openai_sdk_helpers/agent/search/web.py,sha256=vwBKmLNhE6PGswQPjr-sTOPfPURLlwlX7Wm1ysY6w7U,11502
24
+ openai_sdk_helpers/enums/__init__.py,sha256=aFf79C4JBeLC3kMlJfSpehyjx5uNCtW6eK5rD6ZFfhM,322
25
+ openai_sdk_helpers/enums/base.py,sha256=cNllDtzcgI0_eZYXxFko14yhxwicX6xbeDfz9gFE3qo,2753
26
+ openai_sdk_helpers/extract/__init__.py,sha256=T8xtBEm_Mlu5SeXVn4Qv87uGDXed9L0JQaY_gryR1CQ,734
27
+ openai_sdk_helpers/extract/extractor.py,sha256=vmRJyhKDEYAVfRk0KMgLH5hTqUfDAUyWBug5gR3yzcc,5313
28
+ openai_sdk_helpers/extract/generator.py,sha256=K9Euq0IaWs82oe5aRm73_18DelLKYyuH8VhfZ1_ZCEU,14695
29
+ openai_sdk_helpers/prompt/__init__.py,sha256=MOqgKwG9KLqKudoKRlUfLxiSmdOi2aD6hNrWDFqLHkk,418
30
+ openai_sdk_helpers/prompt/base.py,sha256=6X0zeopEvO0ba8207O8Nnj1QvFZEZier7kNNh4qkcmE,7782
31
+ openai_sdk_helpers/prompt/extractor_config_agent_instructions.jinja,sha256=vCrsoUnsgHWSr7OS_ojMUjmPtHfbyv9bzKfaMaCJ99E,329
32
+ openai_sdk_helpers/prompt/extractor_config_generator.jinja,sha256=9rZ1PZdoQtnxDxFUlKRb0SooIEfNw4_Em99n9xvFyyU,960
33
+ openai_sdk_helpers/prompt/extractor_config_generator_instructions.jinja,sha256=GqV3DrGObyER_Fa-GMGGqhWBrQIH9FFlyKdgTjidyzg,534
34
+ openai_sdk_helpers/prompt/extractor_prompt_optimizer_agent_instructions.jinja,sha256=vDCXs1segU-9w9f5Fjp2PfWoXUeOeYw8SBLkAKS8plo,129
35
+ openai_sdk_helpers/prompt/extractor_prompt_optimizer_request.jinja,sha256=YC5uY18CeEXwlnWXOD-vke0npd7Mk-BHRBLjvQzq5lk,280
36
+ openai_sdk_helpers/prompt/summarizer.jinja,sha256=jliSetWDISbql1EkWi1RB8-L_BXUg8JMkRRsPRHuzbY,309
37
+ openai_sdk_helpers/prompt/translator.jinja,sha256=SZhW8ipEzM-9IA4wyS_r2wIMTAclWrilmk1s46njoL0,291
38
+ openai_sdk_helpers/prompt/validator.jinja,sha256=6t8q_IdxFd3mVBGX6SFKNOert1Wo3YpTOji2SNEbbtE,547
39
+ openai_sdk_helpers/prompt/vector_planner.jinja,sha256=szzuJu6ZawYWuARgQn4DykBLigHfCd0lKYM-GRgoR30,282
40
+ openai_sdk_helpers/prompt/vector_search.jinja,sha256=KPEYQDRKsUesadSyQcBBiqYQEDL1NLN6BQsqw-GcKMA,249
41
+ openai_sdk_helpers/prompt/vector_writer.jinja,sha256=q5osfexGvt1xn8ZPtBWUP36n_1HK_Ziu8dkmCZDVamc,342
42
+ openai_sdk_helpers/response/__init__.py,sha256=YFrGpnMIfatnLWXAZgZDMvDx7Yjsqjat8W9INxKuPxY,1728
43
+ openai_sdk_helpers/response/base.py,sha256=pZYc2YpIzg9fYP98XqVN_sTDGRpgqd-UvrBZLfUw0KQ,34791
44
+ openai_sdk_helpers/response/configuration.py,sha256=jxneKd7oj08D40ceOWETB3TeUHd7Cnz-ooQp0akI9fA,10465
45
+ openai_sdk_helpers/response/files.py,sha256=zv5MpYZYHDBum4q9RJH_mVdnKHKOB72EB4nZwTwnlbU,13295
46
+ openai_sdk_helpers/response/messages.py,sha256=qX3sW79rLuJEys28zyv5MovZikwGOaLevzdVN0VYMRE,10104
47
+ openai_sdk_helpers/response/planner.py,sha256=AuNMZkd4TGnvybSJaf2iMbvfPINbusrWucWBk2uQN_g,340
48
+ openai_sdk_helpers/response/prompter.py,sha256=TLRLmNwPcxaaB_X76BbvwXlphducPKYVbn-afTqN2Rk,344
49
+ openai_sdk_helpers/response/runner.py,sha256=3VmWY5du5iBwjVU9D0n2hexu61f561m2iTvhkmq30rc,2932
50
+ openai_sdk_helpers/response/tool_call.py,sha256=Y0ub14WJyuVyj9gRdnHFH2e-ezkfhJ9nnMlkubMKdug,2938
51
+ openai_sdk_helpers/response/vector_store.py,sha256=HClp6O_g20uklQTY7trC4age3rtDmrt3tuvrl93xIf4,3222
52
+ openai_sdk_helpers/streamlit_app/__init__.py,sha256=3yAkl6qV71cqtT5YFZuC9Bkqit0NtffDV6jmMWpT1k4,812
53
+ openai_sdk_helpers/streamlit_app/app.py,sha256=YbCMOOjrC4rxqQP09WcFnHnfpIYYXn-9Tn-NBRGjFJI,17502
54
+ openai_sdk_helpers/streamlit_app/configuration.py,sha256=0KeJ4HqCNFthBHsedV6ptqHluAcTPBb5_TujFOGkIUU,16685
55
+ openai_sdk_helpers/structure/__init__.py,sha256=JRdhEFPLDwty8tuAzCmep59RSknorZ4Dd7cyqonOi4Q,3891
56
+ openai_sdk_helpers/structure/agent_blueprint.py,sha256=VyJWkgPNzAYKRDMeR1M4kE6qqQURnwqtrrEn0TRJf0g,9698
57
+ openai_sdk_helpers/structure/base.py,sha256=nYViUME9pvzMRFIvNORTgwNFcjJdCjd4R1mLMo0nMSM,24822
58
+ openai_sdk_helpers/structure/extraction.py,sha256=wODP0iLAhhsdQkMWRYPYTiLUMU8bFMKiBjPl3PKUleg,37335
59
+ openai_sdk_helpers/structure/prompt.py,sha256=ZfsaHdA0hj5zmZDrOdpXjCsC8U-jjzwFG4JBsWYiaH4,1535
60
+ openai_sdk_helpers/structure/responses.py,sha256=WUwh0DhXj24pkvgqH1FMkdx5V2ArdvdtrDN_fuMBtDU,4882
61
+ openai_sdk_helpers/structure/summary.py,sha256=iP1uffqve18B9HXceP4rV0Ho5AaDZXMmC66tRKDNx3c,3143
62
+ openai_sdk_helpers/structure/translation.py,sha256=rBSzGBX6hGaETD43340z9MbKGsxWekjRD4xEZz67SnI,712
63
+ openai_sdk_helpers/structure/validation.py,sha256=D03rlyBDn22qNjTGaGsjhsk3g50oPmzYMFqycYF2_CU,2409
64
+ openai_sdk_helpers/structure/vector_search.py,sha256=XNQsG6_-c7X6TpXjqWOdKCmqXatX1gwd0zq-hII3cz4,5782
65
+ openai_sdk_helpers/structure/web_search.py,sha256=cPqjwip0xS3OHf7yQ3B_t4VJSlviqgqzPpOkT8_qLvY,4330
66
+ openai_sdk_helpers/structure/plan/__init__.py,sha256=IGr0Tk4inN_8o7fT2N02_FTi6U6l2T9_npcQHAlBwKA,1076
67
+ openai_sdk_helpers/structure/plan/enum.py,sha256=seESSwH-IeeW-9BqIMUQyk3qjtchfU3TDhF9HPDB1OM,3079
68
+ openai_sdk_helpers/structure/plan/helpers.py,sha256=Vc6dBTMFrNWlsaCTpEImEIKjfFq4BSSxNjB4K8dywOQ,5139
69
+ openai_sdk_helpers/structure/plan/plan.py,sha256=yRBx0Z7tog4sGyq7s1kJHvqQOzLpKT8JJ9Ur5j-lhtk,9130
70
+ openai_sdk_helpers/structure/plan/task.py,sha256=DAfgJIa3Yq2AMEzaX20o8SdOs2AlM28pPE9GfbmXk3o,3547
71
+ openai_sdk_helpers/structure/plan/types.py,sha256=7y9QEVdZreQUXV7n-R4RoNZzw5HeOVbJGWx9QkSfuNY,418
72
+ openai_sdk_helpers/utils/__init__.py,sha256=TO8VoKlxCNnrdsLT9iMA5hFwF2mT5SEoTsJzYnLdDKs,3669
73
+ openai_sdk_helpers/utils/async_utils.py,sha256=9KbPEVfi6IXdbwkTUE0h5DleK8TI7I6P_VPL8UgUv98,3689
74
+ openai_sdk_helpers/utils/coercion.py,sha256=Pq1u7tAbD7kTZ84lK-7Fb9CyYKKKQt4fypG5BlSI6oQ,3774
75
+ openai_sdk_helpers/utils/encoding.py,sha256=oDtlNGZ5p-edXiHW76REs-0-8NXkQNReKJdj6sHLkt8,4615
76
+ openai_sdk_helpers/utils/instructions.py,sha256=trbjxjxv2otQR9VmBsPFk1_CJj8nA85Sgtj_5QmQOKI,942
77
+ openai_sdk_helpers/utils/langextract.py,sha256=wkEGbNHDiSX5WVURwCZZZDi23EpHsnO4JR_jJht99C0,5245
78
+ openai_sdk_helpers/utils/output_validation.py,sha256=3DC6Hr6vAFx_bQGaLsxkGN_LuKe_MugLpVogMBgG9tc,12621
79
+ openai_sdk_helpers/utils/path_utils.py,sha256=NOSX7553cc8LqxbnvmdYjgDBi5Le2W2LuMINwFsTzyM,1969
80
+ openai_sdk_helpers/utils/registry.py,sha256=FJvQEZ19vmgfhd1QR5JHb-jIite5fB-bSEOMTGkY7iQ,6680
81
+ openai_sdk_helpers/utils/validation.py,sha256=ZjnZNOy5AoFlszRxarNol6YZwfgw6LnwPtkCekZmwAU,7826
82
+ openai_sdk_helpers/utils/json/__init__.py,sha256=wBm1DBgfy_n1uSUcnCPyqBn_cCq41mijjPigSMZJZqg,2118
83
+ openai_sdk_helpers/utils/json/base_model.py,sha256=DXxKT3CuTNrzUDc9zq7c32EQ18WLyifXG33XOWZxiBk,14122
84
+ openai_sdk_helpers/utils/json/data_class.py,sha256=Bobc5yCZPMh093-0fiWaYNcEH7gUXUV2Itd-tPXH15w,6476
85
+ openai_sdk_helpers/utils/json/ref.py,sha256=FqBIRWIw33Up3rFyTlLYljcuUjg43f6Nu5wX3tOXn54,2809
86
+ openai_sdk_helpers/utils/json/utils.py,sha256=iyc25tnObqXQJWPKLZMVts932GArdKer59KuC8aQKsY,5948
87
+ openai_sdk_helpers/vector_storage/__init__.py,sha256=L5LxO09puh9_yBB9IDTvc1CvVkARVkHqYY1KX3inB4c,975
88
+ openai_sdk_helpers/vector_storage/cleanup.py,sha256=ImWIE-9lli-odD8qIARvmeaa0y8ZD4pYYP-kT0O3178,3552
89
+ openai_sdk_helpers/vector_storage/storage.py,sha256=CcpATTNdeppmMfbQLnhv29hdEfE3wtAVsyKHNCrL-cI,23657
90
+ openai_sdk_helpers/vector_storage/types.py,sha256=jTCcOYMeOpZWvcse0z4T3MVs-RBOPC-fqWTBeQrgafU,1639
91
+ openai_sdk_helpers-0.5.0.dist-info/METADATA,sha256=DoveMw25xYYVHQpPcj8FZjz4oEDvwPPbMALwVeU-fwI,24106
92
+ openai_sdk_helpers-0.5.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
93
+ openai_sdk_helpers-0.5.0.dist-info/entry_points.txt,sha256=gEOD1ZeXe8d2OP-KzUlG-b_9D9yUZTCt-GFW3EDbIIY,63
94
+ openai_sdk_helpers-0.5.0.dist-info/licenses/LICENSE,sha256=CUhc1NrE50bs45tcXF7OcTQBKEvkUuLqeOHgrWQ5jaA,1067
95
+ openai_sdk_helpers-0.5.0.dist-info/RECORD,,
@@ -1,15 +0,0 @@
1
- """Shared helpers for locating bundled prompt templates.
2
-
3
- Attributes
4
- ----------
5
- DEFAULT_PROMPT_DIR : Path
6
- Default directory containing bundled prompt templates.
7
- """
8
-
9
- from __future__ import annotations
10
-
11
- from pathlib import Path
12
-
13
- DEFAULT_PROMPT_DIR = Path(__file__).resolve().parent.parent / "prompt"
14
-
15
- __all__ = ["DEFAULT_PROMPT_DIR"]
@@ -1,241 +0,0 @@
1
- """Context manager utilities for resource cleanup.
2
-
3
- Provides base classes and utilities for proper resource management
4
- with guaranteed cleanup on exit or exception.
5
- """
6
-
7
- from __future__ import annotations
8
-
9
- import asyncio
10
- from contextlib import asynccontextmanager
11
- from types import TracebackType
12
- from typing import Any, AsyncIterator, Generic, Optional, TypeVar
13
-
14
- from openai_sdk_helpers.logging_config import log
15
-
16
- T = TypeVar("T")
17
-
18
-
19
- class ManagedResource(Generic[T]):
20
- """Base class for resources that need cleanup.
21
-
22
- Provides context manager support for guaranteed resource cleanup
23
- even when exceptions occur.
24
-
25
- Examples
26
- --------
27
- >>> class DatabaseConnection(ManagedResource[Connection]):
28
- ... def __init__(self, connection):
29
- ... self.connection = connection
30
- ...
31
- ... def close(self) -> None:
32
- ... if self.connection:
33
- ... self.connection.close()
34
-
35
- >>> with DatabaseConnection(connect()) as db:
36
- ... db.query("SELECT ...")
37
- """
38
-
39
- def __enter__(self) -> T:
40
- """Enter context manager.
41
-
42
- Returns
43
- -------
44
- T
45
- The resource instance (self cast appropriately).
46
- """
47
- return self # type: ignore
48
-
49
- def __exit__(
50
- self,
51
- exc_type: Optional[type[BaseException]],
52
- exc_val: Optional[BaseException],
53
- exc_tb: Optional[TracebackType],
54
- ) -> bool:
55
- """Exit context manager with cleanup.
56
-
57
- Parameters
58
- ----------
59
- exc_type : type[BaseException] | None
60
- Type of exception if one was raised, None otherwise.
61
- exc_val : BaseException | None
62
- Exception instance if one was raised, None otherwise.
63
- exc_tb : TracebackType | None
64
- Traceback if exception was raised, None otherwise.
65
-
66
- Returns
67
- -------
68
- bool
69
- False to re-raise exceptions, True to suppress them.
70
- """
71
- try:
72
- self.close()
73
- except Exception as exc:
74
- log(f"Error during cleanup: {exc}", level=30) # logging.WARNING
75
- # Don't suppress cleanup errors
76
- if exc_type is None:
77
- raise
78
-
79
- return False # Re-raise exceptions
80
-
81
- def close(self) -> None:
82
- """Close and cleanup the resource.
83
-
84
- Should be overridden by subclasses to perform actual cleanup.
85
- Should not raise exceptions, but may log them.
86
-
87
- Raises
88
- ------
89
- Exception
90
- May raise if cleanup fails catastrophically.
91
- """
92
- pass
93
-
94
-
95
- class AsyncManagedResource(Generic[T]):
96
- """Base class for async resources that need cleanup.
97
-
98
- Provides async context manager support for guaranteed resource cleanup
99
- even when exceptions occur.
100
-
101
- Examples
102
- --------
103
- >>> class AsyncDatabaseConnection(AsyncManagedResource[AsyncConnection]):
104
- ... def __init__(self, connection):
105
- ... self.connection = connection
106
- ...
107
- ... async def close(self) -> None:
108
- ... if self.connection:
109
- ... await self.connection.close()
110
-
111
- >>> async with AsyncDatabaseConnection(await connect()) as db:
112
- ... await db.query("SELECT ...")
113
- """
114
-
115
- async def __aenter__(self) -> T:
116
- """Enter async context manager.
117
-
118
- Returns
119
- -------
120
- T
121
- The resource instance (self cast appropriately).
122
- """
123
- return self # type: ignore
124
-
125
- async def __aexit__(
126
- self,
127
- exc_type: Optional[type[BaseException]],
128
- exc_val: Optional[BaseException],
129
- exc_tb: Optional[TracebackType],
130
- ) -> bool:
131
- """Exit async context manager with cleanup.
132
-
133
- Parameters
134
- ----------
135
- exc_type : type[BaseException] | None
136
- Type of exception if one was raised, None otherwise.
137
- exc_val : BaseException | None
138
- Exception instance if one was raised, None otherwise.
139
- exc_tb : TracebackType | None
140
- Traceback if exception was raised, None otherwise.
141
-
142
- Returns
143
- -------
144
- bool
145
- False to re-raise exceptions, True to suppress them.
146
- """
147
- try:
148
- await self.close()
149
- except Exception as exc:
150
- log(f"Error during async cleanup: {exc}", level=30) # logging.WARNING
151
- # Don't suppress cleanup errors
152
- if exc_type is None:
153
- raise
154
-
155
- return False # Re-raise exceptions
156
-
157
- async def close(self) -> None:
158
- """Close and cleanup the resource asynchronously.
159
-
160
- Should be overridden by subclasses to perform actual cleanup.
161
- Should not raise exceptions, but may log them.
162
-
163
- Raises
164
- ------
165
- Exception
166
- May raise if cleanup fails catastrophically.
167
- """
168
- pass
169
-
170
-
171
- def ensure_closed(resource: Any) -> None:
172
- """Safely close a resource if it has a close method.
173
-
174
- Logs errors but doesn't raise them.
175
-
176
- Parameters
177
- ----------
178
- resource : Any
179
- Object that may have a close() method.
180
- """
181
- if resource is None:
182
- return
183
-
184
- close_method = getattr(resource, "close", None)
185
- if callable(close_method):
186
- try:
187
- close_method()
188
- except Exception as exc:
189
- log(f"Error closing {type(resource).__name__}: {exc}", level=30)
190
-
191
-
192
- async def ensure_closed_async(resource: Any) -> None:
193
- """Safely close a resource asynchronously if it has an async close method.
194
-
195
- Logs errors but doesn't raise them.
196
-
197
- Parameters
198
- ----------
199
- resource : Any
200
- Object that may have an async close() method.
201
- """
202
- if resource is None:
203
- return
204
-
205
- close_method = getattr(resource, "close", None)
206
- if callable(close_method):
207
- try:
208
- if asyncio.iscoroutinefunction(close_method):
209
- await close_method()
210
- else:
211
- close_method()
212
- except Exception as exc:
213
- log(
214
- f"Error closing async {type(resource).__name__}: {exc}",
215
- level=30,
216
- )
217
-
218
-
219
- @asynccontextmanager
220
- async def async_context(resource: AsyncManagedResource[T]) -> AsyncIterator[T]:
221
- """Context manager for async resources.
222
-
223
- Parameters
224
- ----------
225
- resource : AsyncManagedResource
226
- Async resource to manage.
227
-
228
- Yields
229
- ------
230
- T
231
- The resource instance.
232
-
233
- Examples
234
- --------
235
- >>> async with async_context(my_resource) as resource:
236
- ... await resource.do_something()
237
- """
238
- try:
239
- yield await resource.__aenter__()
240
- finally:
241
- await resource.__aexit__(None, None, None)