openai-sdk-helpers 0.2.0__py3-none-any.whl → 0.4.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 (58) hide show
  1. openai_sdk_helpers/__init__.py +6 -6
  2. openai_sdk_helpers/agent/__init__.py +4 -2
  3. openai_sdk_helpers/agent/base.py +391 -106
  4. openai_sdk_helpers/agent/config.py +405 -44
  5. openai_sdk_helpers/agent/coordination.py +68 -31
  6. openai_sdk_helpers/agent/runner.py +29 -19
  7. openai_sdk_helpers/agent/search/base.py +103 -54
  8. openai_sdk_helpers/agent/search/vector.py +99 -68
  9. openai_sdk_helpers/agent/search/web.py +84 -50
  10. openai_sdk_helpers/agent/summarizer.py +33 -7
  11. openai_sdk_helpers/agent/translator.py +58 -24
  12. openai_sdk_helpers/agent/validation.py +35 -4
  13. openai_sdk_helpers/cli.py +42 -0
  14. openai_sdk_helpers/config.py +0 -1
  15. openai_sdk_helpers/environment.py +3 -2
  16. openai_sdk_helpers/files_api.py +35 -3
  17. openai_sdk_helpers/prompt/base.py +6 -0
  18. openai_sdk_helpers/response/__init__.py +3 -3
  19. openai_sdk_helpers/response/base.py +161 -22
  20. openai_sdk_helpers/response/config.py +50 -200
  21. openai_sdk_helpers/response/files.py +5 -5
  22. openai_sdk_helpers/response/messages.py +3 -3
  23. openai_sdk_helpers/response/runner.py +7 -7
  24. openai_sdk_helpers/response/tool_call.py +94 -4
  25. openai_sdk_helpers/response/vector_store.py +3 -3
  26. openai_sdk_helpers/streamlit_app/app.py +16 -16
  27. openai_sdk_helpers/streamlit_app/config.py +38 -37
  28. openai_sdk_helpers/streamlit_app/streamlit_web_search.py +2 -2
  29. openai_sdk_helpers/structure/__init__.py +6 -2
  30. openai_sdk_helpers/structure/agent_blueprint.py +2 -2
  31. openai_sdk_helpers/structure/base.py +8 -99
  32. openai_sdk_helpers/structure/plan/plan.py +2 -2
  33. openai_sdk_helpers/structure/plan/task.py +9 -9
  34. openai_sdk_helpers/structure/prompt.py +2 -2
  35. openai_sdk_helpers/structure/responses.py +15 -15
  36. openai_sdk_helpers/structure/summary.py +3 -3
  37. openai_sdk_helpers/structure/translation.py +32 -0
  38. openai_sdk_helpers/structure/validation.py +2 -2
  39. openai_sdk_helpers/structure/vector_search.py +7 -7
  40. openai_sdk_helpers/structure/web_search.py +6 -6
  41. openai_sdk_helpers/tools.py +41 -15
  42. openai_sdk_helpers/utils/__init__.py +19 -5
  43. openai_sdk_helpers/utils/instructions.py +35 -0
  44. openai_sdk_helpers/utils/json/__init__.py +55 -0
  45. openai_sdk_helpers/utils/json/base_model.py +181 -0
  46. openai_sdk_helpers/utils/{json_utils.py → json/data_class.py} +43 -70
  47. openai_sdk_helpers/utils/json/ref.py +113 -0
  48. openai_sdk_helpers/utils/json/utils.py +203 -0
  49. openai_sdk_helpers/utils/output_validation.py +21 -1
  50. openai_sdk_helpers/utils/path_utils.py +34 -1
  51. openai_sdk_helpers/utils/registry.py +194 -0
  52. openai_sdk_helpers/vector_storage/storage.py +10 -0
  53. {openai_sdk_helpers-0.2.0.dist-info → openai_sdk_helpers-0.4.0.dist-info}/METADATA +7 -7
  54. openai_sdk_helpers-0.4.0.dist-info/RECORD +86 -0
  55. openai_sdk_helpers-0.2.0.dist-info/RECORD +0 -79
  56. {openai_sdk_helpers-0.2.0.dist-info → openai_sdk_helpers-0.4.0.dist-info}/WHEEL +0 -0
  57. {openai_sdk_helpers-0.2.0.dist-info → openai_sdk_helpers-0.4.0.dist-info}/entry_points.txt +0 -0
  58. {openai_sdk_helpers-0.2.0.dist-info → openai_sdk_helpers-0.4.0.dist-info}/licenses/LICENSE +0 -0
@@ -16,7 +16,7 @@ from ...structure.web_search import (
16
16
  WebSearchPlanStructure,
17
17
  WebSearchReportStructure,
18
18
  )
19
- from ..config import AgentConfig
19
+ from ..config import AgentConfiguration
20
20
  from ..utils import run_coroutine_agent_sync
21
21
  from .base import SearchPlanner, SearchToolAgent, SearchWriter
22
22
 
@@ -26,38 +26,47 @@ MAX_CONCURRENT_SEARCHES = 10
26
26
  class WebAgentPlanner(SearchPlanner[WebSearchPlanStructure]):
27
27
  """Plan web searches to satisfy a user query.
28
28
 
29
+ Parameters
30
+ ----------
31
+ prompt_dir : Path or None, default=None
32
+ Directory containing prompt templates.
33
+ default_model : str or None, default=None
34
+ Default model identifier to use when not defined in config.
35
+
29
36
  Methods
30
37
  -------
31
38
  run_agent(query)
32
39
  Generate a search plan for the provided query.
40
+
41
+ Raises
42
+ ------
43
+ ValueError
44
+ If the default model is not provided.
45
+
46
+ Examples
47
+ --------
48
+ >>> planner = WebAgentPlanner(default_model="gpt-4o-mini")
33
49
  """
34
50
 
35
51
  def __init__(
36
52
  self, prompt_dir: Optional[Path] = None, default_model: Optional[str] = None
37
53
  ) -> None:
38
- """Initialize the planner agent.
39
-
40
- Parameters
41
- ----------
42
- prompt_dir : Path or None, default=None
43
- Directory containing prompt templates.
44
- default_model : str or None, default=None
45
- Default model identifier to use when not defined in config.
46
- """
54
+ """Initialize the planner agent."""
47
55
  super().__init__(prompt_dir=prompt_dir, default_model=default_model)
48
56
 
49
- def _configure_agent(self) -> AgentConfig:
57
+ def _configure_agent(self) -> AgentConfiguration:
50
58
  """Return configuration for the web planner agent.
51
59
 
52
60
  Returns
53
61
  -------
54
- AgentConfig
62
+ AgentConfiguration
55
63
  Configuration with name, description, and output type.
56
64
  """
57
- return AgentConfig(
65
+ return AgentConfiguration(
58
66
  name="web_planner",
67
+ instructions="Agent instructions",
59
68
  description="Agent that plans web searches based on a user query.",
60
- output_type=WebSearchPlanStructure,
69
+ output_structure=WebSearchPlanStructure,
61
70
  )
62
71
 
63
72
 
@@ -68,44 +77,53 @@ class WebSearchToolAgent(
68
77
  ):
69
78
  """Execute web searches defined in a plan.
70
79
 
80
+ Parameters
81
+ ----------
82
+ prompt_dir : Path or None, default=None
83
+ Directory containing prompt templates.
84
+ default_model : str or None, default=None
85
+ Default model identifier to use when not defined in config.
86
+
71
87
  Methods
72
88
  -------
73
89
  run_agent(search_plan)
74
90
  Execute searches described by the plan.
75
91
  run_search(item)
76
92
  Perform a single web search and summarise the result.
93
+
94
+ Raises
95
+ ------
96
+ ValueError
97
+ If the default model is not provided.
98
+
99
+ Examples
100
+ --------
101
+ >>> tool = WebSearchToolAgent(default_model="gpt-4o-mini")
77
102
  """
78
103
 
79
104
  def __init__(
80
105
  self, prompt_dir: Optional[Path] = None, default_model: Optional[str] = None
81
106
  ) -> None:
82
- """Initialize the search tool agent.
83
-
84
- Parameters
85
- ----------
86
- prompt_dir : Path or None, default=None
87
- Directory containing prompt templates.
88
- default_model : str or None, default=None
89
- Default model identifier to use when not defined in config.
90
- """
107
+ """Initialize the search tool agent."""
91
108
  super().__init__(
92
109
  prompt_dir=prompt_dir,
93
110
  default_model=default_model,
94
111
  max_concurrent_searches=MAX_CONCURRENT_SEARCHES,
95
112
  )
96
113
 
97
- def _configure_agent(self) -> AgentConfig:
114
+ def _configure_agent(self) -> AgentConfiguration:
98
115
  """Return configuration for the web search tool agent.
99
116
 
100
117
  Returns
101
118
  -------
102
- AgentConfig
119
+ AgentConfiguration
103
120
  Configuration with name, description, input type, and tools.
104
121
  """
105
- return AgentConfig(
122
+ return AgentConfiguration(
106
123
  name="web_search",
124
+ instructions="Agent instructions",
107
125
  description="Agent that performs web searches and summarizes results.",
108
- input_type=WebSearchPlanStructure,
126
+ input_structure=WebSearchPlanStructure,
109
127
  tools=[WebSearchTool()],
110
128
  model_settings=ModelSettings(tool_choice="required"),
111
129
  )
@@ -134,7 +152,6 @@ class WebSearchToolAgent(
134
152
  result = await super(SearchToolAgent, self).run_async(
135
153
  input=item.query,
136
154
  context=template_context,
137
- output_type=str,
138
155
  )
139
156
  return self._coerce_item_result(result)
140
157
 
@@ -165,44 +182,60 @@ class WebSearchToolAgent(
165
182
  class WebAgentWriter(SearchWriter[WebSearchReportStructure]):
166
183
  """Summarize search results into a human-readable report.
167
184
 
185
+ Parameters
186
+ ----------
187
+ prompt_dir : Path or None, default=None
188
+ Directory containing prompt templates.
189
+ default_model : str or None, default=None
190
+ Default model identifier to use when not defined in config.
191
+
168
192
  Methods
169
193
  -------
170
194
  run_agent(query, search_results)
171
195
  Compile a report from search results.
196
+
197
+ Raises
198
+ ------
199
+ ValueError
200
+ If the default model is not provided.
201
+
202
+ Examples
203
+ --------
204
+ >>> writer = WebAgentWriter(default_model="gpt-4o-mini")
172
205
  """
173
206
 
174
207
  def __init__(
175
208
  self, prompt_dir: Optional[Path] = None, default_model: Optional[str] = None
176
209
  ) -> None:
177
- """Initialize the writer agent.
178
-
179
- Parameters
180
- ----------
181
- prompt_dir : Path or None, default=None
182
- Directory containing prompt templates.
183
- default_model : str or None, default=None
184
- Default model identifier to use when not defined in config.
185
- """
210
+ """Initialize the writer agent."""
186
211
  super().__init__(prompt_dir=prompt_dir, default_model=default_model)
187
212
 
188
- def _configure_agent(self) -> AgentConfig:
213
+ def _configure_agent(self) -> AgentConfiguration:
189
214
  """Return configuration for the web writer agent.
190
215
 
191
216
  Returns
192
217
  -------
193
- AgentConfig
218
+ AgentConfiguration
194
219
  Configuration with name, description, and output type.
195
220
  """
196
- return AgentConfig(
221
+ return AgentConfiguration(
197
222
  name="web_writer",
223
+ instructions="Agent instructions",
198
224
  description="Agent that writes a report based on web search results.",
199
- output_type=WebSearchReportStructure,
225
+ output_structure=WebSearchReportStructure,
200
226
  )
201
227
 
202
228
 
203
229
  class WebAgentSearch:
204
230
  """Manage the complete web search workflow.
205
231
 
232
+ Parameters
233
+ ----------
234
+ prompt_dir : Path or None, default=None
235
+ Directory containing prompt templates.
236
+ default_model : str or None, default=None
237
+ Default model identifier to use when not defined in config.
238
+
206
239
  Methods
207
240
  -------
208
241
  run_agent_async(search_query)
@@ -213,6 +246,15 @@ class WebAgentSearch:
213
246
  Convenience asynchronous entry point for the workflow.
214
247
  run_web_agent_sync(search_query)
215
248
  Convenience synchronous entry point for the workflow.
249
+
250
+ Raises
251
+ ------
252
+ ValueError
253
+ If the default model is not provided.
254
+
255
+ Examples
256
+ --------
257
+ >>> search = WebAgentSearch(default_model="gpt-4o-mini")
216
258
  """
217
259
 
218
260
  def __init__(
@@ -220,15 +262,7 @@ class WebAgentSearch:
220
262
  prompt_dir: Optional[Path] = None,
221
263
  default_model: Optional[str] = None,
222
264
  ) -> None:
223
- """Create the main web search agent.
224
-
225
- Parameters
226
- ----------
227
- prompt_dir : Path or None, default=None
228
- Directory containing prompt templates.
229
- default_model : str or None, default=None
230
- Default model identifier to use when not defined in config.
231
- """
265
+ """Create the main web search agent."""
232
266
  self._prompt_dir = prompt_dir
233
267
  self._default_model = default_model
234
268
 
@@ -3,11 +3,12 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  from pathlib import Path
6
- from typing import Any, Dict, Optional
6
+ from typing import Any, Dict, Optional, Type
7
7
 
8
8
  from ..structure import SummaryStructure
9
+ from ..structure.base import StructureBase
9
10
  from .base import AgentBase
10
- from .config import AgentConfig
11
+ from .config import AgentConfiguration
11
12
  from .prompt_utils import DEFAULT_PROMPT_DIR
12
13
 
13
14
 
@@ -18,6 +19,16 @@ class SummarizerAgent(AgentBase):
18
19
  content. The output follows the ``SummaryStructure`` format by default but
19
20
  can be customized with a different output type.
20
21
 
22
+ Parameters
23
+ ----------
24
+ prompt_dir : Path or None, default=None
25
+ Optional directory containing Jinja prompt templates. Defaults to the
26
+ packaged ``prompt`` directory when not provided.
27
+ default_model : str or None, default=None
28
+ Fallback model identifier when not specified elsewhere.
29
+ output_structure : type[StructureBase], default=SummaryStructure
30
+ Type describing the expected summary output.
31
+
21
32
  Examples
22
33
  --------
23
34
  Basic usage with default settings:
@@ -50,7 +61,7 @@ class SummarizerAgent(AgentBase):
50
61
  *,
51
62
  prompt_dir: Optional[Path] = None,
52
63
  default_model: Optional[str] = None,
53
- output_type: type[Any] = SummaryStructure,
64
+ output_structure: Type[StructureBase] = SummaryStructure,
54
65
  ) -> None:
55
66
  """Initialize the summarizer agent configuration.
56
67
 
@@ -61,13 +72,23 @@ class SummarizerAgent(AgentBase):
61
72
  packaged ``prompt`` directory when not provided.
62
73
  default_model : str or None, default=None
63
74
  Fallback model identifier when not specified elsewhere.
64
- output_type : type, default=SummaryStructure
75
+ output_structure : type[StructureBase], default=SummaryStructure
65
76
  Type describing the expected summary output.
77
+
78
+ Raises
79
+ ------
80
+ ValueError
81
+ If the default model is not provided.
82
+
83
+ Examples
84
+ --------
85
+ >>> summarizer = SummarizerAgent(default_model="gpt-4o-mini")
66
86
  """
67
- config = AgentConfig(
87
+ config = AgentConfiguration(
68
88
  name="summarizer",
89
+ instructions="Agent instructions",
69
90
  description="Summarize passages into concise findings.",
70
- output_type=output_type,
91
+ output_structure=output_structure,
71
92
  )
72
93
  prompt_directory = prompt_dir or DEFAULT_PROMPT_DIR
73
94
  super().__init__(
@@ -90,6 +111,11 @@ class SummarizerAgent(AgentBase):
90
111
  -------
91
112
  Any
92
113
  Structured summary produced by the agent.
114
+
115
+ Raises
116
+ ------
117
+ APIError
118
+ If the OpenAI API call fails.
93
119
  """
94
120
  context: Optional[Dict[str, Any]] = None
95
121
  if metadata:
@@ -98,7 +124,7 @@ class SummarizerAgent(AgentBase):
98
124
  result = await self.run_async(
99
125
  input=text,
100
126
  context=context,
101
- output_type=self._output_type,
127
+ output_structure=self._output_structure,
102
128
  )
103
129
  return result
104
130
 
@@ -6,8 +6,10 @@ from pathlib import Path
6
6
  from typing import Any, Dict, Optional
7
7
 
8
8
  from .base import AgentBase
9
- from .config import AgentConfig
9
+ from .config import AgentConfiguration
10
10
  from .prompt_utils import DEFAULT_PROMPT_DIR
11
+ from ..structure import TranslationStructure
12
+ from ..structure.base import StructureBase
11
13
 
12
14
 
13
15
  class TranslatorAgent(AgentBase):
@@ -16,6 +18,14 @@ class TranslatorAgent(AgentBase):
16
18
  This agent provides language translation services using OpenAI models,
17
19
  supporting both synchronous and asynchronous execution modes.
18
20
 
21
+ Parameters
22
+ ----------
23
+ prompt_dir : Path or None, default=None
24
+ Optional directory containing Jinja prompt templates. Defaults to the
25
+ packaged ``prompt`` directory when not provided.
26
+ default_model : str or None, default=None
27
+ Fallback model identifier when not specified elsewhere.
28
+
19
29
  Examples
20
30
  --------
21
31
  Basic translation:
@@ -23,7 +33,7 @@ class TranslatorAgent(AgentBase):
23
33
  >>> from openai_sdk_helpers.agent import TranslatorAgent
24
34
  >>> translator = TranslatorAgent(default_model="gpt-4o-mini")
25
35
  >>> result = translator.run_sync("Hello world", target_language="Spanish")
26
- >>> print(result)
36
+ >>> print(result.text)
27
37
  'Hola mundo'
28
38
 
29
39
  Async translation with context:
@@ -62,11 +72,21 @@ class TranslatorAgent(AgentBase):
62
72
  packaged ``prompt`` directory when not provided.
63
73
  default_model : str or None, default=None
64
74
  Fallback model identifier when not specified elsewhere.
75
+
76
+ Raises
77
+ ------
78
+ ValueError
79
+ If the default model is not provided.
80
+
81
+ Examples
82
+ --------
83
+ >>> translator = TranslatorAgent(default_model="gpt-4o-mini")
65
84
  """
66
- config = AgentConfig(
85
+ config = AgentConfiguration(
67
86
  name="translator",
87
+ instructions="Agent instructions",
68
88
  description="Translate text into the requested language.",
69
- output_type=str,
89
+ output_structure=TranslationStructure,
70
90
  )
71
91
  prompt_directory = prompt_dir or DEFAULT_PROMPT_DIR
72
92
  super().__init__(
@@ -78,7 +98,7 @@ class TranslatorAgent(AgentBase):
78
98
  text: str,
79
99
  target_language: str,
80
100
  context: Optional[Dict[str, Any]] = None,
81
- ) -> str:
101
+ ) -> TranslationStructure:
82
102
  """Translate ``text`` to ``target_language``.
83
103
 
84
104
  Parameters
@@ -92,29 +112,41 @@ class TranslatorAgent(AgentBase):
92
112
 
93
113
  Returns
94
114
  -------
95
- str
96
- Translated text returned by the agent.
115
+ TranslationStructure
116
+ Structured translation output from the agent.
117
+
118
+ Raises
119
+ ------
120
+ APIError
121
+ If the OpenAI API call fails.
122
+
123
+ Examples
124
+ --------
125
+ >>> import asyncio
126
+ >>> async def main():
127
+ ... result = await translator.run_agent("Hello", "Spanish")
128
+ ... return result
129
+ >>> asyncio.run(main())
97
130
  """
98
131
  template_context: Dict[str, Any] = {"target_language": target_language}
99
132
  if context:
100
133
  template_context.update(context)
101
134
 
102
- result: str = await self.run_async(
135
+ result: TranslationStructure = await self.run_async(
103
136
  input=text,
104
137
  context=template_context,
105
- output_type=str,
106
138
  )
107
139
  return result
108
140
 
109
141
  def run_sync(
110
142
  self,
111
143
  input: str,
112
- context: Optional[Dict[str, Any]] = None,
113
- output_type: Optional[Any] = None,
114
144
  *,
145
+ context: Optional[Dict[str, Any]] = None,
146
+ output_structure: Optional[type[StructureBase]] = None,
147
+ session: Optional[Any] = None,
115
148
  target_language: Optional[str] = None,
116
- **kwargs: Any,
117
- ) -> str:
149
+ ) -> TranslationStructure:
118
150
  """Translate ``input`` to ``target_language`` synchronously.
119
151
 
120
152
  Parameters
@@ -123,31 +155,32 @@ class TranslatorAgent(AgentBase):
123
155
  Source content to translate.
124
156
  context : dict or None, default=None
125
157
  Additional context values to merge into the prompt.
126
- output_type : type or None, default=None
158
+ output_structure : type[StructureBase] or None, default=None
127
159
  Optional output type cast for the response.
128
160
  target_language : str or None, optional
129
161
  Target language to translate the content into. Required unless supplied
130
- within ``context`` or ``kwargs``.
131
- **kwargs
132
- Optional keyword arguments. ``context`` is accepted as an alias for
133
- backward compatibility.
162
+ within ``context``.
163
+ session : Session or None, default=None
164
+ Optional session for maintaining conversation history across runs.
134
165
 
135
166
  Returns
136
167
  -------
137
- str
138
- Translated text returned by the agent.
168
+ TranslationStructure
169
+ Structured translation output from the agent.
139
170
 
140
171
  Raises
141
172
  ------
142
173
  ValueError
143
174
  If ``target_language`` is not provided.
175
+
176
+ Examples
177
+ --------
178
+ >>> result = translator.run_sync("Hello", target_language="Spanish")
144
179
  """
145
180
  merged_context: Dict[str, Any] = {}
146
181
 
147
182
  if context:
148
183
  merged_context.update(context)
149
- if "context" in kwargs and kwargs["context"]:
150
- merged_context.update(kwargs["context"])
151
184
  if target_language:
152
185
  merged_context["target_language"] = target_language
153
186
 
@@ -155,10 +188,11 @@ class TranslatorAgent(AgentBase):
155
188
  msg = "target_language is required for translation"
156
189
  raise ValueError(msg)
157
190
 
158
- result: str = super().run_sync(
191
+ result: TranslationStructure = super().run_sync(
159
192
  input=input,
160
193
  context=merged_context,
161
- output_type=output_type or str,
194
+ output_structure=output_structure or self._output_structure,
195
+ session=session,
162
196
  )
163
197
  return result
164
198
 
@@ -7,7 +7,7 @@ from typing import Any, Dict, Optional
7
7
 
8
8
  from ..structure.validation import ValidationResultStructure
9
9
  from .base import AgentBase
10
- from .config import AgentConfig
10
+ from .config import AgentConfiguration
11
11
  from .prompt_utils import DEFAULT_PROMPT_DIR
12
12
 
13
13
 
@@ -18,6 +18,14 @@ class ValidatorAgent(AgentBase):
18
18
  policies and usage guidelines, returning structured validation results with
19
19
  recommended actions.
20
20
 
21
+ Parameters
22
+ ----------
23
+ prompt_dir : Path or None, default=None
24
+ Optional directory containing Jinja prompt templates. Defaults to the
25
+ packaged ``prompt`` directory when not provided.
26
+ default_model : str or None, default=None
27
+ Fallback model identifier when not specified elsewhere.
28
+
21
29
  Examples
22
30
  --------
23
31
  Validate user input:
@@ -63,11 +71,21 @@ class ValidatorAgent(AgentBase):
63
71
  packaged ``prompt`` directory when not provided.
64
72
  default_model : str or None, default=None
65
73
  Fallback model identifier when not specified elsewhere.
74
+
75
+ Raises
76
+ ------
77
+ ValueError
78
+ If the default model is not provided.
79
+
80
+ Examples
81
+ --------
82
+ >>> validator = ValidatorAgent(default_model="gpt-4o-mini")
66
83
  """
67
- config = AgentConfig(
84
+ config = AgentConfiguration(
68
85
  name="validator",
86
+ instructions="Agent instructions",
69
87
  description="Validate user input and agent output against guardrails.",
70
- output_type=ValidationResultStructure,
88
+ output_structure=ValidationResultStructure,
71
89
  )
72
90
  prompt_directory = prompt_dir or DEFAULT_PROMPT_DIR
73
91
  super().__init__(
@@ -101,6 +119,19 @@ class ValidatorAgent(AgentBase):
101
119
  -------
102
120
  ValidationResultStructure
103
121
  Structured validation result describing any violations and actions.
122
+
123
+ Raises
124
+ ------
125
+ APIError
126
+ If the OpenAI API call fails.
127
+
128
+ Examples
129
+ --------
130
+ >>> import asyncio
131
+ >>> async def main():
132
+ ... result = await validator.run_agent("Safe input")
133
+ ... return result
134
+ >>> asyncio.run(main())
104
135
  """
105
136
  context: Dict[str, Any] = {"user_input": user_input}
106
137
  if agent_output is not None:
@@ -113,7 +144,7 @@ class ValidatorAgent(AgentBase):
113
144
  result: ValidationResultStructure = await self.run_async(
114
145
  input=user_input,
115
146
  context=context,
116
- output_type=ValidationResultStructure,
147
+ output_structure=ValidationResultStructure,
117
148
  )
118
149
  return result
119
150
 
openai_sdk_helpers/cli.py CHANGED
@@ -43,6 +43,15 @@ def cmd_agent_test(args: argparse.Namespace) -> int:
43
43
  -------
44
44
  int
45
45
  Exit code (0 for success).
46
+
47
+ Raises
48
+ ------
49
+ NotImplementedError
50
+ As the function is not yet implemented.
51
+
52
+ Examples
53
+ --------
54
+ >>> cmd_agent_test(argparse.Namespace(agent_name="test", input="hello"))
46
55
  """
47
56
  print(f"Testing agent: {args.agent_name}")
48
57
  print(f"Input: {args.input}")
@@ -62,6 +71,15 @@ def cmd_template_validate(args: argparse.Namespace) -> int:
62
71
  -------
63
72
  int
64
73
  Exit code (0 for success, 1 for validation errors).
74
+
75
+ Raises
76
+ ------
77
+ FileNotFoundError
78
+ If the template path does not exist.
79
+
80
+ Examples
81
+ --------
82
+ >>> cmd_template_validate(argparse.Namespace(template_path="."))
65
83
  """
66
84
  from jinja2 import Environment, FileSystemLoader, TemplateSyntaxError
67
85
 
@@ -116,6 +134,15 @@ def cmd_registry_list(args: argparse.Namespace) -> int:
116
134
  -------
117
135
  int
118
136
  Exit code (0 for success).
137
+
138
+ Raises
139
+ ------
140
+ ImportError
141
+ If openai_sdk_helpers is not installed.
142
+
143
+ Examples
144
+ --------
145
+ >>> cmd_registry_list(argparse.Namespace())
119
146
  """
120
147
  try:
121
148
  from openai_sdk_helpers import get_default_registry
@@ -151,6 +178,17 @@ def cmd_registry_inspect(args: argparse.Namespace) -> int:
151
178
  -------
152
179
  int
153
180
  Exit code (0 for success, 1 for not found).
181
+
182
+ Raises
183
+ ------
184
+ ImportError
185
+ If openai_sdk_helpers is not installed.
186
+ KeyError
187
+ If the configuration is not found in the registry.
188
+
189
+ Examples
190
+ --------
191
+ >>> cmd_registry_inspect(argparse.Namespace(config_name="my_config"))
154
192
  """
155
193
  try:
156
194
  from openai_sdk_helpers import get_default_registry
@@ -198,6 +236,10 @@ def main(argv: list[str] | None = None) -> int:
198
236
  -------
199
237
  int
200
238
  Exit code.
239
+
240
+ Examples
241
+ --------
242
+ >>> main(["agent", "test", "my_agent"])
201
243
  """
202
244
  parser = argparse.ArgumentParser(
203
245
  prog="openai-helpers",
@@ -156,7 +156,6 @@ class OpenAISettings(BaseModel):
156
156
  return first_non_none(
157
157
  overrides.get(override_key),
158
158
  env_file_values.get(env_var),
159
- os.getenv(env_var),
160
159
  )
161
160
  return first_non_none(
162
161
  overrides.get(override_key),
@@ -40,7 +40,7 @@ def get_data_path(name: str) -> Path:
40
40
  Returns
41
41
  -------
42
42
  Path
43
- Directory path under ~/.openai-sdk-helpers specific to name.
43
+ Directory path under ~/openai-sdk-helpers specific to name.
44
44
  The directory is created if it does not exist.
45
45
 
46
46
  Examples
@@ -50,6 +50,7 @@ def get_data_path(name: str) -> Path:
50
50
  >>> path.exists()
51
51
  True
52
52
  """
53
- base = Path.home() / ".openai-sdk-helpers"
53
+ # Use the workspace 'data' directory, with a subdirectory for the module name
54
+ base = Path(__file__).parent.parent.parent / "data"
54
55
  path = base / name
55
56
  return ensure_directory(path)