openai-sdk-helpers 0.1.4__py3-none-any.whl → 0.3.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.
@@ -12,8 +12,8 @@ from abc import ABC, abstractmethod
12
12
  from pathlib import Path
13
13
  from typing import Generic, List, Optional, TypeVar, Union
14
14
 
15
- from ..base import AgentBase
16
- from ..config import AgentConfig
15
+ from ..base import BaseAgent
16
+ from ..config import AgentConfiguration
17
17
 
18
18
  # Type variables for search workflow components
19
19
  ItemType = TypeVar("ItemType") # Search item structure (e.g., WebSearchItemStructure)
@@ -23,7 +23,7 @@ ReportType = TypeVar("ReportType") # Final report structure
23
23
  OutputType = TypeVar("OutputType") # Generic output type
24
24
 
25
25
 
26
- class SearchPlanner(AgentBase, Generic[PlanType]):
26
+ class SearchPlanner(BaseAgent, Generic[PlanType]):
27
27
  """Generic planner agent for search workflows.
28
28
 
29
29
  Subclasses implement specific planner logic by overriding the
@@ -34,7 +34,7 @@ class SearchPlanner(AgentBase, Generic[PlanType]):
34
34
  run_agent(query)
35
35
  Generate a search plan for the provided query.
36
36
  _configure_agent()
37
- Return AgentConfig for this planner instance.
37
+ Return AgentConfiguration for this planner instance.
38
38
  """
39
39
 
40
40
  def __init__(
@@ -59,17 +59,17 @@ class SearchPlanner(AgentBase, Generic[PlanType]):
59
59
  )
60
60
 
61
61
  @abstractmethod
62
- def _configure_agent(self) -> AgentConfig:
62
+ def _configure_agent(self) -> AgentConfiguration:
63
63
  """Return configuration for this planner.
64
64
 
65
65
  Returns
66
66
  -------
67
- AgentConfig
67
+ AgentConfiguration
68
68
  Configuration with name, description, and output_type set.
69
69
 
70
70
  Examples
71
71
  --------
72
- >>> config = AgentConfig(
72
+ >>> config = AgentConfiguration(
73
73
  ... name="web_planner",
74
74
  ... description="Plan web searches",
75
75
  ... output_type=WebSearchPlanStructure,
@@ -98,7 +98,7 @@ class SearchPlanner(AgentBase, Generic[PlanType]):
98
98
  return result
99
99
 
100
100
 
101
- class SearchToolAgent(AgentBase, Generic[ItemType, ResultType, PlanType]):
101
+ class SearchToolAgent(BaseAgent, Generic[ItemType, ResultType, PlanType]):
102
102
  """Generic tool agent for executing search workflows.
103
103
 
104
104
  Executes individual searches in a plan with concurrency control.
@@ -112,7 +112,7 @@ class SearchToolAgent(AgentBase, Generic[ItemType, ResultType, PlanType]):
112
112
  run_search(item)
113
113
  Execute a single search item.
114
114
  _configure_agent()
115
- Return AgentConfig for this tool agent.
115
+ Return AgentConfiguration for this tool agent.
116
116
  """
117
117
 
118
118
  def __init__(
@@ -142,17 +142,17 @@ class SearchToolAgent(AgentBase, Generic[ItemType, ResultType, PlanType]):
142
142
  )
143
143
 
144
144
  @abstractmethod
145
- def _configure_agent(self) -> AgentConfig:
145
+ def _configure_agent(self) -> AgentConfiguration:
146
146
  """Return configuration for this tool agent.
147
147
 
148
148
  Returns
149
149
  -------
150
- AgentConfig
150
+ AgentConfiguration
151
151
  Configuration with name, description, input_type, and tools set.
152
152
 
153
153
  Examples
154
154
  --------
155
- >>> config = AgentConfig(
155
+ >>> config = AgentConfiguration(
156
156
  ... name="web_search",
157
157
  ... description="Perform web searches",
158
158
  ... input_type=WebSearchPlanStructure,
@@ -205,7 +205,7 @@ class SearchToolAgent(AgentBase, Generic[ItemType, ResultType, PlanType]):
205
205
  return [result for result in results if result is not None]
206
206
 
207
207
 
208
- class SearchWriter(AgentBase, Generic[ReportType]):
208
+ class SearchWriter(BaseAgent, Generic[ReportType]):
209
209
  """Generic writer agent for search workflow reports.
210
210
 
211
211
  Synthesizes search results into a final report. Subclasses implement
@@ -216,7 +216,7 @@ class SearchWriter(AgentBase, Generic[ReportType]):
216
216
  run_agent(query, search_results)
217
217
  Generate a report from search results.
218
218
  _configure_agent()
219
- Return AgentConfig for this writer instance.
219
+ Return AgentConfiguration for this writer instance.
220
220
  """
221
221
 
222
222
  def __init__(
@@ -241,17 +241,17 @@ class SearchWriter(AgentBase, Generic[ReportType]):
241
241
  )
242
242
 
243
243
  @abstractmethod
244
- def _configure_agent(self) -> AgentConfig:
244
+ def _configure_agent(self) -> AgentConfiguration:
245
245
  """Return configuration for this writer.
246
246
 
247
247
  Returns
248
248
  -------
249
- AgentConfig
249
+ AgentConfiguration
250
250
  Configuration with name, description, and output_type set.
251
251
 
252
252
  Examples
253
253
  --------
254
- >>> config = AgentConfig(
254
+ >>> config = AgentConfiguration(
255
255
  ... name="web_writer",
256
256
  ... description="Write web search report",
257
257
  ... output_type=WebSearchReportStructure,
@@ -16,7 +16,7 @@ from ...structure.vector_search import (
16
16
  VectorSearchReportStructure,
17
17
  )
18
18
  from ...vector_storage import VectorStorage
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
 
@@ -46,16 +46,17 @@ class VectorSearchPlanner(SearchPlanner[VectorSearchPlanStructure]):
46
46
  """
47
47
  super().__init__(prompt_dir=prompt_dir, default_model=default_model)
48
48
 
49
- def _configure_agent(self) -> AgentConfig:
49
+ def _configure_agent(self) -> AgentConfiguration:
50
50
  """Return configuration for the vector planner agent.
51
51
 
52
52
  Returns
53
53
  -------
54
- AgentConfig
54
+ AgentConfiguration
55
55
  Configuration with name, description, and output type.
56
56
  """
57
- return AgentConfig(
57
+ return AgentConfiguration(
58
58
  name="vector_planner",
59
+ instructions="Agent instructions",
59
60
  description="Plan vector searches based on a user query.",
60
61
  output_type=VectorSearchPlanStructure,
61
62
  )
@@ -117,16 +118,17 @@ class VectorSearchTool(
117
118
  max_concurrent_searches=max_concurrent_searches,
118
119
  )
119
120
 
120
- def _configure_agent(self) -> AgentConfig:
121
+ def _configure_agent(self) -> AgentConfiguration:
121
122
  """Return configuration for the vector search tool agent.
122
123
 
123
124
  Returns
124
125
  -------
125
- AgentConfig
126
+ AgentConfiguration
126
127
  Configuration with name, description, and input type.
127
128
  """
128
- return AgentConfig(
129
+ return AgentConfiguration(
129
130
  name="vector_search",
131
+ instructions="Agent instructions",
130
132
  description="Perform vector searches based on a search plan.",
131
133
  input_type=VectorSearchPlanStructure,
132
134
  output_type=VectorSearchItemResultsStructure,
@@ -199,16 +201,17 @@ class VectorSearchWriter(SearchWriter[VectorSearchReportStructure]):
199
201
  """
200
202
  super().__init__(prompt_dir=prompt_dir, default_model=default_model)
201
203
 
202
- def _configure_agent(self) -> AgentConfig:
204
+ def _configure_agent(self) -> AgentConfiguration:
203
205
  """Return configuration for the vector writer agent.
204
206
 
205
207
  Returns
206
208
  -------
207
- AgentConfig
209
+ AgentConfiguration
208
210
  Configuration with name, description, and output type.
209
211
  """
210
- return AgentConfig(
212
+ return AgentConfiguration(
211
213
  name="vector_writer",
214
+ instructions="Agent instructions",
212
215
  description="Write a report based on search results.",
213
216
  output_type=VectorSearchReportStructure,
214
217
  )
@@ -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
 
@@ -46,16 +46,17 @@ class WebAgentPlanner(SearchPlanner[WebSearchPlanStructure]):
46
46
  """
47
47
  super().__init__(prompt_dir=prompt_dir, default_model=default_model)
48
48
 
49
- def _configure_agent(self) -> AgentConfig:
49
+ def _configure_agent(self) -> AgentConfiguration:
50
50
  """Return configuration for the web planner agent.
51
51
 
52
52
  Returns
53
53
  -------
54
- AgentConfig
54
+ AgentConfiguration
55
55
  Configuration with name, description, and output type.
56
56
  """
57
- return AgentConfig(
57
+ return AgentConfiguration(
58
58
  name="web_planner",
59
+ instructions="Agent instructions",
59
60
  description="Agent that plans web searches based on a user query.",
60
61
  output_type=WebSearchPlanStructure,
61
62
  )
@@ -94,16 +95,17 @@ class WebSearchToolAgent(
94
95
  max_concurrent_searches=MAX_CONCURRENT_SEARCHES,
95
96
  )
96
97
 
97
- def _configure_agent(self) -> AgentConfig:
98
+ def _configure_agent(self) -> AgentConfiguration:
98
99
  """Return configuration for the web search tool agent.
99
100
 
100
101
  Returns
101
102
  -------
102
- AgentConfig
103
+ AgentConfiguration
103
104
  Configuration with name, description, input type, and tools.
104
105
  """
105
- return AgentConfig(
106
+ return AgentConfiguration(
106
107
  name="web_search",
108
+ instructions="Agent instructions",
107
109
  description="Agent that performs web searches and summarizes results.",
108
110
  input_type=WebSearchPlanStructure,
109
111
  tools=[WebSearchTool()],
@@ -185,16 +187,17 @@ class WebAgentWriter(SearchWriter[WebSearchReportStructure]):
185
187
  """
186
188
  super().__init__(prompt_dir=prompt_dir, default_model=default_model)
187
189
 
188
- def _configure_agent(self) -> AgentConfig:
190
+ def _configure_agent(self) -> AgentConfiguration:
189
191
  """Return configuration for the web writer agent.
190
192
 
191
193
  Returns
192
194
  -------
193
- AgentConfig
195
+ AgentConfiguration
194
196
  Configuration with name, description, and output type.
195
197
  """
196
- return AgentConfig(
198
+ return AgentConfiguration(
197
199
  name="web_writer",
200
+ instructions="Agent instructions",
198
201
  description="Agent that writes a report based on web search results.",
199
202
  output_type=WebSearchReportStructure,
200
203
  )
@@ -6,12 +6,12 @@ from pathlib import Path
6
6
  from typing import Any, Dict, Optional
7
7
 
8
8
  from ..structure import SummaryStructure
9
- from .base import AgentBase
10
- from .config import AgentConfig
9
+ from .base import BaseAgent
10
+ from .config import AgentConfiguration
11
11
  from .prompt_utils import DEFAULT_PROMPT_DIR
12
12
 
13
13
 
14
- class SummarizerAgent(AgentBase):
14
+ class SummarizerAgent(BaseAgent):
15
15
  """Generate concise summaries from provided text.
16
16
 
17
17
  This agent uses OpenAI models to create structured summaries from longer-form
@@ -64,8 +64,9 @@ class SummarizerAgent(AgentBase):
64
64
  output_type : type, default=SummaryStructure
65
65
  Type describing the expected summary output.
66
66
  """
67
- config = AgentConfig(
67
+ config = AgentConfiguration(
68
68
  name="summarizer",
69
+ instructions="Agent instructions",
69
70
  description="Summarize passages into concise findings.",
70
71
  output_type=output_type,
71
72
  )
@@ -5,12 +5,12 @@ from __future__ import annotations
5
5
  from pathlib import Path
6
6
  from typing import Any, Dict, Optional
7
7
 
8
- from .base import AgentBase
9
- from .config import AgentConfig
8
+ from .base import BaseAgent
9
+ from .config import AgentConfiguration
10
10
  from .prompt_utils import DEFAULT_PROMPT_DIR
11
11
 
12
12
 
13
- class TranslatorAgent(AgentBase):
13
+ class TranslatorAgent(BaseAgent):
14
14
  """Translate text into a target language.
15
15
 
16
16
  This agent provides language translation services using OpenAI models,
@@ -63,8 +63,9 @@ class TranslatorAgent(AgentBase):
63
63
  default_model : str or None, default=None
64
64
  Fallback model identifier when not specified elsewhere.
65
65
  """
66
- config = AgentConfig(
66
+ config = AgentConfiguration(
67
67
  name="translator",
68
+ instructions="Agent instructions",
68
69
  description="Translate text into the requested language.",
69
70
  output_type=str,
70
71
  )
@@ -6,12 +6,12 @@ from pathlib import Path
6
6
  from typing import Any, Dict, Optional
7
7
 
8
8
  from ..structure.validation import ValidationResultStructure
9
- from .base import AgentBase
10
- from .config import AgentConfig
9
+ from .base import BaseAgent
10
+ from .config import AgentConfiguration
11
11
  from .prompt_utils import DEFAULT_PROMPT_DIR
12
12
 
13
13
 
14
- class ValidatorAgent(AgentBase):
14
+ class ValidatorAgent(BaseAgent):
15
15
  """Check user prompts and agent responses against safety guardrails.
16
16
 
17
17
  This agent validates inputs and outputs to ensure they comply with safety
@@ -64,8 +64,9 @@ class ValidatorAgent(AgentBase):
64
64
  default_model : str or None, default=None
65
65
  Fallback model identifier when not specified elsewhere.
66
66
  """
67
- config = AgentConfig(
67
+ config = AgentConfiguration(
68
68
  name="validator",
69
+ instructions="Agent instructions",
69
70
  description="Validate user input and agent output against guardrails.",
70
71
  output_type=ValidationResultStructure,
71
72
  )
@@ -56,6 +56,7 @@ from ..utils import (
56
56
 
57
57
  if TYPE_CHECKING: # pragma: no cover - only for typing hints
58
58
  from openai_sdk_helpers.streamlit_app.config import StreamlitAppConfig
59
+ from .config import ResponseConfiguration
59
60
 
60
61
  T = TypeVar("T", bound=BaseStructure)
61
62
  ToolHandler = Callable[[ResponseFunctionToolCall], str | Any]
@@ -126,10 +127,10 @@ class BaseResponse(Generic[T]):
126
127
  instructions: str,
127
128
  tools: list | None,
128
129
  output_structure: type[T] | None,
129
- tool_handlers: dict[str, ToolHandler],
130
- openai_settings: OpenAISettings,
131
130
  system_vector_store: list[str] | None = None,
132
131
  data_path: Path | str | None = None,
132
+ tool_handlers: dict[str, ToolHandler] | None = None,
133
+ openai_settings: OpenAISettings | None = None,
133
134
  ) -> None:
134
135
  """Initialize a response session with OpenAI configuration.
135
136
 
@@ -150,18 +151,19 @@ class BaseResponse(Generic[T]):
150
151
  Structure class used to parse tool call outputs. When provided,
151
152
  the schema is automatically generated using the structure's
152
153
  response_format() method. Pass None for unstructured responses.
153
- tool_handlers : dict[str, ToolHandler]
154
- Mapping from tool names to callable handlers. Each handler receives
155
- a ResponseFunctionToolCall and returns a string or any serializable
156
- result.
157
- openai_settings : OpenAISettings
158
- Fully configured OpenAI settings with API key and default model.
159
154
  system_vector_store : list[str] or None, default None
160
155
  Optional list of vector store names to attach as system context.
161
156
  data_path : Path, str, or None, default None
162
157
  Optional absolute directory path for storing artifacts. If not provided,
163
158
  defaults to get_data_path(class_name). Session files are saved as
164
159
  data_path / uuid.json.
160
+ tool_handlers : dict[str, ToolHandler] or None, default None
161
+ Mapping from tool names to callable handlers. Each handler receives
162
+ a ResponseFunctionToolCall and returns a string or any serializable
163
+ result. Defaults to an empty dict when not provided.
164
+ openai_settings : OpenAISettings or None, default None
165
+ Fully configured OpenAI settings with API key and default model.
166
+ Required for normal operation.
165
167
 
166
168
  Raises
167
169
  ------
@@ -184,6 +186,11 @@ class BaseResponse(Generic[T]):
184
186
  ... openai_settings=settings,
185
187
  ... )
186
188
  """
189
+ if tool_handlers is None:
190
+ tool_handlers = {}
191
+ if openai_settings is None:
192
+ raise ValueError("openai_settings is required")
193
+
187
194
  self._tool_handlers = tool_handlers
188
195
  self._name = name
189
196
 
@@ -247,11 +254,80 @@ class BaseResponse(Generic[T]):
247
254
  ),
248
255
  )
249
256
 
257
+ # Add retrieval guidance to system instructions to encourage RAG usage
258
+ try:
259
+ store_names = ", ".join(system_vector_store)
260
+ except Exception:
261
+ store_names = "attached vector stores"
262
+ guidance_text = (
263
+ "Retrieval guidance: You have access to a file_search tool "
264
+ f"connected to vector store(s) {store_names}. When relevant, "
265
+ "use file_search to retrieve supporting passages before answering. "
266
+ "Cite or reference retrieved content when helpful."
267
+ )
268
+ system_content.append(
269
+ ResponseInputTextParam(type="input_text", text=guidance_text)
270
+ )
271
+
250
272
  self.messages = ResponseMessages()
251
273
  self.messages.add_system_message(content=system_content)
252
274
  if self._data_path is not None:
253
275
  self.save()
254
276
 
277
+ @classmethod
278
+ def from_configuration(
279
+ cls: type[RB],
280
+ config: "ResponseConfiguration[Any, T]",
281
+ *,
282
+ openai_settings: OpenAISettings,
283
+ tool_handlers: dict[str, ToolHandler] | None = None,
284
+ add_output_instructions: bool = True,
285
+ ) -> RB:
286
+ """Construct a response instance from a configuration object.
287
+
288
+ Parameters
289
+ ----------
290
+ config : ResponseConfiguration
291
+ Configuration describing the response inputs, outputs, and tools.
292
+ openai_settings : OpenAISettings
293
+ OpenAI authentication and model configuration used for the response.
294
+ tool_handlers : dict[str, ToolHandler] or None, default None
295
+ Mapping of tool names to callable handlers. Defaults to an empty
296
+ dictionary when not provided.
297
+ add_output_instructions : bool, default True
298
+ Append structured output instructions when an output structure is
299
+ present.
300
+
301
+ Returns
302
+ -------
303
+ BaseResponse
304
+ Instance of ``cls`` configured from ``config``.
305
+ """
306
+ handlers = tool_handlers or {}
307
+
308
+ output_instructions = ""
309
+ if config.output_structure is not None and add_output_instructions:
310
+ output_instructions = config.output_structure.get_prompt(
311
+ add_enum_values=False
312
+ )
313
+
314
+ instructions = (
315
+ f"{config.instructions_text}\n{output_instructions}"
316
+ if output_instructions
317
+ else config.instructions_text
318
+ )
319
+
320
+ return cls(
321
+ name=config.name,
322
+ instructions=instructions,
323
+ tools=config.tools,
324
+ output_structure=config.output_structure,
325
+ system_vector_store=config.system_vector_store,
326
+ data_path=config.data_path,
327
+ tool_handlers=handlers,
328
+ openai_settings=openai_settings,
329
+ )
330
+
255
331
  @property
256
332
  def name(self) -> str:
257
333
  """Return the name of this response session.