openai-sdk-helpers 0.0.7__py3-none-any.whl → 0.0.9__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 (63) hide show
  1. openai_sdk_helpers/__init__.py +85 -10
  2. openai_sdk_helpers/agent/__init__.py +8 -4
  3. openai_sdk_helpers/agent/base.py +81 -46
  4. openai_sdk_helpers/agent/config.py +6 -4
  5. openai_sdk_helpers/agent/{project_manager.py → coordination.py} +29 -45
  6. openai_sdk_helpers/agent/prompt_utils.py +7 -1
  7. openai_sdk_helpers/agent/runner.py +67 -141
  8. openai_sdk_helpers/agent/search/__init__.py +33 -0
  9. openai_sdk_helpers/agent/search/base.py +297 -0
  10. openai_sdk_helpers/agent/{vector_search.py → search/vector.py} +89 -157
  11. openai_sdk_helpers/agent/{web_search.py → search/web.py} +82 -162
  12. openai_sdk_helpers/agent/summarizer.py +29 -8
  13. openai_sdk_helpers/agent/translator.py +40 -13
  14. openai_sdk_helpers/agent/validation.py +32 -8
  15. openai_sdk_helpers/async_utils.py +132 -0
  16. openai_sdk_helpers/config.py +74 -36
  17. openai_sdk_helpers/context_manager.py +241 -0
  18. openai_sdk_helpers/enums/__init__.py +9 -1
  19. openai_sdk_helpers/enums/base.py +67 -8
  20. openai_sdk_helpers/environment.py +33 -6
  21. openai_sdk_helpers/errors.py +133 -0
  22. openai_sdk_helpers/logging_config.py +105 -0
  23. openai_sdk_helpers/prompt/__init__.py +10 -71
  24. openai_sdk_helpers/prompt/base.py +172 -0
  25. openai_sdk_helpers/response/__init__.py +37 -5
  26. openai_sdk_helpers/response/base.py +427 -189
  27. openai_sdk_helpers/response/config.py +176 -0
  28. openai_sdk_helpers/response/messages.py +104 -40
  29. openai_sdk_helpers/response/runner.py +79 -35
  30. openai_sdk_helpers/response/tool_call.py +75 -12
  31. openai_sdk_helpers/response/vector_store.py +29 -16
  32. openai_sdk_helpers/retry.py +175 -0
  33. openai_sdk_helpers/streamlit_app/__init__.py +30 -0
  34. openai_sdk_helpers/streamlit_app/app.py +345 -0
  35. openai_sdk_helpers/streamlit_app/config.py +502 -0
  36. openai_sdk_helpers/streamlit_app/streamlit_web_search.py +68 -0
  37. openai_sdk_helpers/structure/__init__.py +69 -3
  38. openai_sdk_helpers/structure/agent_blueprint.py +82 -19
  39. openai_sdk_helpers/structure/base.py +245 -91
  40. openai_sdk_helpers/structure/plan/__init__.py +15 -1
  41. openai_sdk_helpers/structure/plan/enum.py +41 -5
  42. openai_sdk_helpers/structure/plan/plan.py +101 -45
  43. openai_sdk_helpers/structure/plan/task.py +38 -6
  44. openai_sdk_helpers/structure/prompt.py +21 -2
  45. openai_sdk_helpers/structure/responses.py +52 -11
  46. openai_sdk_helpers/structure/summary.py +55 -7
  47. openai_sdk_helpers/structure/validation.py +34 -6
  48. openai_sdk_helpers/structure/vector_search.py +132 -18
  49. openai_sdk_helpers/structure/web_search.py +128 -12
  50. openai_sdk_helpers/types.py +57 -0
  51. openai_sdk_helpers/utils/__init__.py +32 -1
  52. openai_sdk_helpers/utils/core.py +200 -32
  53. openai_sdk_helpers/validation.py +302 -0
  54. openai_sdk_helpers/vector_storage/__init__.py +21 -1
  55. openai_sdk_helpers/vector_storage/cleanup.py +25 -13
  56. openai_sdk_helpers/vector_storage/storage.py +124 -66
  57. openai_sdk_helpers/vector_storage/types.py +20 -19
  58. openai_sdk_helpers-0.0.9.dist-info/METADATA +550 -0
  59. openai_sdk_helpers-0.0.9.dist-info/RECORD +66 -0
  60. openai_sdk_helpers-0.0.7.dist-info/METADATA +0 -193
  61. openai_sdk_helpers-0.0.7.dist-info/RECORD +0 -51
  62. {openai_sdk_helpers-0.0.7.dist-info → openai_sdk_helpers-0.0.9.dist-info}/WHEEL +0 -0
  63. {openai_sdk_helpers-0.0.7.dist-info → openai_sdk_helpers-0.0.9.dist-info}/licenses/LICENSE +0 -0
@@ -1,8 +1,10 @@
1
- """Structures describing guardrail validation results."""
1
+ """Structures describing guardrail validation results.
2
2
 
3
- from __future__ import annotations
3
+ This module defines Pydantic models for representing the results of guardrail
4
+ validation checks on user inputs and agent outputs.
5
+ """
4
6
 
5
- from typing import List, Optional
7
+ from __future__ import annotations
6
8
 
7
9
  from .base import BaseStructure, spec_field
8
10
 
@@ -10,10 +12,36 @@ from .base import BaseStructure, spec_field
10
12
  class ValidationResultStructure(BaseStructure):
11
13
  """Capture guardrail validation findings for user and agent messages.
12
14
 
15
+ Represents the results of safety and policy validation checks performed
16
+ on both user inputs and agent outputs, including detected violations
17
+ and recommended remediation actions.
18
+
19
+ Attributes
20
+ ----------
21
+ input_safe : bool
22
+ Whether the user-provided input is allowed within the guardrails.
23
+ output_safe : bool
24
+ Whether the agent output adheres to the safety guardrails.
25
+ violations : list[str]
26
+ Detected policy or safety issues that require mitigation.
27
+ recommended_actions : list[str]
28
+ Steps to remediate or respond to any detected violations.
29
+ sanitized_output : str or None
30
+ Optional redacted or rewritten text that fits the guardrails.
31
+
13
32
  Methods
14
33
  -------
15
34
  print()
16
35
  Return a formatted string representation of the stored fields.
36
+
37
+ Examples
38
+ --------
39
+ >>> result = ValidationResultStructure(
40
+ ... input_safe=True,
41
+ ... output_safe=True,
42
+ ... violations=[],
43
+ ... recommended_actions=[]
44
+ ... )
17
45
  """
18
46
 
19
47
  input_safe: bool = spec_field(
@@ -26,19 +54,19 @@ class ValidationResultStructure(BaseStructure):
26
54
  allow_null=False,
27
55
  description="Whether the agent output adheres to the safety guardrails.",
28
56
  )
29
- violations: List[str] = spec_field(
57
+ violations: list[str] = spec_field(
30
58
  "violations",
31
59
  allow_null=False,
32
60
  default_factory=list,
33
61
  description="Detected policy or safety issues that require mitigation.",
34
62
  )
35
- recommended_actions: List[str] = spec_field(
63
+ recommended_actions: list[str] = spec_field(
36
64
  "recommended_actions",
37
65
  allow_null=False,
38
66
  default_factory=list,
39
67
  description="Steps to remediate or respond to any detected violations.",
40
68
  )
41
- sanitized_output: Optional[str] = spec_field(
69
+ sanitized_output: str | None = spec_field(
42
70
  "sanitized_output",
43
71
  description="Optional redacted or rewritten text that fits the guardrails.",
44
72
  )
@@ -1,47 +1,108 @@
1
- """Shared structured output models for vector search."""
1
+ """Structured output models for vector search workflows.
2
2
 
3
- from __future__ import annotations
3
+ This module defines Pydantic models for representing vector search plans,
4
+ results, and reports. These structures support multi-query vector search
5
+ workflows with error tracking and result aggregation.
6
+ """
4
7
 
5
- from typing import List
8
+ from __future__ import annotations
6
9
 
7
10
  from .base import BaseStructure, spec_field
8
11
 
9
12
 
10
13
  class VectorSearchItemStructure(BaseStructure):
11
- """A single vector search to perform."""
14
+ """A single vector search to perform.
15
+
16
+ Represents one vector search query with rationale for its inclusion
17
+ in a multi-query search plan.
18
+
19
+ Attributes
20
+ ----------
21
+ reason : str
22
+ Explanation for why this search is needed.
23
+ query : str
24
+ Vector search query text.
25
+
26
+ Examples
27
+ --------
28
+ >>> item = VectorSearchItemStructure(
29
+ ... reason="Find related documents",
30
+ ... query="machine learning trends"
31
+ ... )
32
+ """
12
33
 
13
34
  reason: str = spec_field("reason")
14
35
  query: str = spec_field("query")
15
36
 
16
37
 
17
38
  class VectorSearchPlanStructure(BaseStructure):
18
- """Collection of vector searches required to satisfy the query."""
39
+ """Collection of vector searches required to satisfy the query.
19
40
 
20
- searches: List[VectorSearchItemStructure] = spec_field("searches")
41
+ Represents a plan containing multiple vector searches that together
42
+ provide comprehensive coverage for answering a user query.
43
+
44
+ Attributes
45
+ ----------
46
+ searches : list[VectorSearchItemStructure]
47
+ List of vector search queries to execute.
48
+
49
+ Examples
50
+ --------
51
+ >>> plan = VectorSearchPlanStructure(
52
+ ... searches=[VectorSearchItemStructure(reason="R", query="Q")]
53
+ ... )
54
+ """
55
+
56
+ searches: list[VectorSearchItemStructure] = spec_field("searches")
21
57
 
22
58
 
23
59
  class VectorSearchItemResultStructure(BaseStructure):
24
- """Result of a single vector search."""
60
+ """Result of a single vector search.
25
61
 
26
- texts: List[str] = spec_field("texts")
62
+ Contains the text results retrieved from executing one vector search query.
63
+
64
+ Attributes
65
+ ----------
66
+ texts : list[str]
67
+ Retrieved text passages from the vector search.
68
+
69
+ Examples
70
+ --------
71
+ >>> result = VectorSearchItemResultStructure(texts=["Result 1", "Result 2"])
72
+ """
73
+
74
+ texts: list[str] = spec_field("texts")
27
75
 
28
76
 
29
77
  class VectorSearchItemResultsStructure(BaseStructure):
30
- """Collection of search results returned from multiple queries.
78
+ """Collection of search results from multiple queries.
31
79
 
32
- Failed searches are recorded in ``errors`` to allow callers to inspect
33
- partial outcomes without losing visibility into issues.
80
+ Aggregates results from multiple vector searches while tracking any
81
+ errors encountered. Failed searches are recorded in the errors list
82
+ to allow inspection of partial outcomes.
83
+
84
+ Attributes
85
+ ----------
86
+ item_results : list[VectorSearchItemResultStructure]
87
+ List of successful search results.
88
+ errors : list[str]
89
+ List of error messages from failed searches.
34
90
 
35
91
  Methods
36
92
  -------
37
93
  append(item)
38
94
  Add a search result to the collection.
95
+
96
+ Examples
97
+ --------
98
+ >>> results = VectorSearchItemResultsStructure()
99
+ >>> results.append(VectorSearchItemResultStructure(texts=["Text"]))
39
100
  """
40
101
 
41
- item_results: List[VectorSearchItemResultStructure] = spec_field(
102
+ item_results: list[VectorSearchItemResultStructure] = spec_field(
42
103
  "item_results", default_factory=list
43
104
  )
44
- errors: List[str] = spec_field("errors", default_factory=list)
105
+ errors: list[str] = spec_field("errors", default_factory=list)
45
106
 
46
107
  def append(self, item: VectorSearchItemResultStructure) -> None:
47
108
  """Add a search result to the collection.
@@ -59,16 +120,69 @@ class VectorSearchItemResultsStructure(BaseStructure):
59
120
 
60
121
 
61
122
  class VectorSearchReportStructure(BaseStructure):
62
- """Structured output from the vector search writer agent."""
123
+ """Structured output from the vector search writer agent.
124
+
125
+ Contains the final synthesized report from vector search results,
126
+ including summary, markdown report, follow-up questions, and sources.
127
+
128
+ Attributes
129
+ ----------
130
+ short_summary : str
131
+ Brief summary of the search findings.
132
+ markdown_report : str
133
+ Full markdown-formatted report.
134
+ follow_up_questions : list[str]
135
+ Suggested questions for further exploration.
136
+ sources : list[str]
137
+ Source references used in the report.
138
+
139
+ Examples
140
+ --------
141
+ >>> report = VectorSearchReportStructure(
142
+ ... short_summary="Summary",
143
+ ... markdown_report="# Report",
144
+ ... follow_up_questions=["Q1?"],
145
+ ... sources=["Source 1"]
146
+ ... )
147
+ """
63
148
 
64
149
  short_summary: str = spec_field("short_summary")
65
150
  markdown_report: str = spec_field("markdown_report")
66
- follow_up_questions: List[str] = spec_field("follow_up_questions")
67
- sources: List[str] = spec_field("sources")
151
+ follow_up_questions: list[str] = spec_field("follow_up_questions")
152
+ sources: list[str] = spec_field("sources")
68
153
 
69
154
 
70
155
  class VectorSearchStructure(BaseStructure):
71
- """Complete output of a vector search workflow."""
156
+ """Complete output of a vector search workflow.
157
+
158
+ Represents the full lifecycle of a vector search operation, from the
159
+ original query through plan generation, execution, and final report.
160
+
161
+ Attributes
162
+ ----------
163
+ query : str
164
+ Original user query.
165
+ plan : VectorSearchPlanStructure
166
+ Generated search plan.
167
+ results : VectorSearchItemResultsStructure
168
+ Aggregated search results.
169
+ report : VectorSearchReportStructure
170
+ Final synthesized report.
171
+
172
+ Examples
173
+ --------
174
+ >>> workflow = VectorSearchStructure(
175
+ ... query="Test query",
176
+ ... plan=VectorSearchPlanStructure(searches=[]),
177
+ ... results=VectorSearchItemResultsStructure(),
178
+ ... report=VectorSearchReportStructure(
179
+ ... short_summary="S",
180
+ ... markdown_report="R",
181
+ ... follow_up_questions=[],
182
+ ... sources=[]
183
+ ... )
184
+ ... )
185
+ """
72
186
 
73
187
  query: str = spec_field("query")
74
188
  plan: VectorSearchPlanStructure = spec_field("plan")
@@ -79,8 +193,8 @@ class VectorSearchStructure(BaseStructure):
79
193
  __all__ = [
80
194
  "VectorSearchReportStructure",
81
195
  "VectorSearchItemStructure",
196
+ "VectorSearchPlanStructure",
82
197
  "VectorSearchItemResultStructure",
83
198
  "VectorSearchItemResultsStructure",
84
- "VectorSearchPlanStructure",
85
199
  "VectorSearchStructure",
86
200
  ]
@@ -1,46 +1,162 @@
1
- """Shared structured output model for web search results."""
1
+ """Structured output models for web search workflows.
2
2
 
3
- from __future__ import annotations
3
+ This module defines Pydantic models for representing web search plans,
4
+ results, and reports. These structures support multi-query web search
5
+ workflows with comprehensive reporting.
6
+ """
4
7
 
5
- from typing import List
8
+ from __future__ import annotations
6
9
 
7
10
  from .base import BaseStructure, spec_field
8
11
 
9
12
 
10
13
  class WebSearchReportStructure(BaseStructure):
11
- """Structured output from the writer agent."""
14
+ """Structured output from the web search writer agent.
15
+
16
+ Contains the final synthesized report from web search results,
17
+ including summary, markdown report, follow-up questions, and sources.
18
+
19
+ Attributes
20
+ ----------
21
+ short_summary : str
22
+ Brief summary of the search findings.
23
+ markdown_report : str
24
+ Full markdown-formatted report.
25
+ follow_up_questions : list[str]
26
+ Suggested questions for further exploration.
27
+ sources : list[str]
28
+ Source URLs and references used in the report.
29
+
30
+ Examples
31
+ --------
32
+ >>> report = WebSearchReportStructure(
33
+ ... short_summary="Summary",
34
+ ... markdown_report="# Report",
35
+ ... follow_up_questions=["Q1?"],
36
+ ... sources=["https://example.com"]
37
+ ... )
38
+ """
12
39
 
13
40
  short_summary: str = spec_field("short_summary")
14
41
  markdown_report: str = spec_field("markdown_report")
15
- follow_up_questions: List[str] = spec_field("follow_up_questions")
16
- sources: List[str] = spec_field("sources")
42
+ follow_up_questions: list[str] = spec_field("follow_up_questions")
43
+ sources: list[str] = spec_field("sources")
17
44
 
18
45
 
19
46
  class WebSearchItemStructure(BaseStructure):
20
- """A single web search to perform."""
47
+ """A single web search to perform.
48
+
49
+ Represents one web search query with rationale for its inclusion
50
+ in a multi-query search plan.
51
+
52
+ Attributes
53
+ ----------
54
+ reason : str
55
+ Explanation for why this search is needed.
56
+ query : str
57
+ Web search query text.
58
+
59
+ Examples
60
+ --------
61
+ >>> item = WebSearchItemStructure(
62
+ ... reason="Find latest news",
63
+ ... query="AI developments 2024"
64
+ ... )
65
+ """
21
66
 
22
67
  reason: str = spec_field("reason")
23
68
  query: str = spec_field("query")
24
69
 
25
70
 
26
71
  class WebSearchItemResultStructure(BaseStructure):
27
- """Result of a single web search."""
72
+ """Result of a single web search.
73
+
74
+ Contains the text content retrieved from executing one web search query.
75
+
76
+ Attributes
77
+ ----------
78
+ text : str
79
+ Retrieved text content from the web search.
80
+
81
+ Examples
82
+ --------
83
+ >>> result = WebSearchItemResultStructure(text="Search result content")
84
+ """
28
85
 
29
86
  text: str = spec_field("text")
30
87
 
31
88
 
32
89
  class WebSearchPlanStructure(BaseStructure):
33
- """Collection of searches required to satisfy the query."""
90
+ """Collection of web searches required to satisfy the query.
34
91
 
35
- searches: List[WebSearchItemStructure] = spec_field("searches")
92
+ Represents a plan containing multiple web searches that together
93
+ provide comprehensive coverage for answering a user query.
94
+
95
+ Attributes
96
+ ----------
97
+ searches : list[WebSearchItemStructure]
98
+ List of web search queries to execute.
99
+
100
+ Examples
101
+ --------
102
+ >>> plan = WebSearchPlanStructure(
103
+ ... searches=[WebSearchItemStructure(reason="R", query="Q")]
104
+ ... )
105
+ """
106
+
107
+ searches: list[WebSearchItemStructure] = spec_field("searches")
36
108
 
37
109
 
38
110
  class WebSearchStructure(BaseStructure):
39
- """Complete output of a web search workflow."""
111
+ """Complete output of a web search workflow.
112
+
113
+ Represents the full lifecycle of a web search operation, from the
114
+ original query through plan generation, execution, and final report.
115
+
116
+ Attributes
117
+ ----------
118
+ query : str
119
+ Original user query.
120
+ web_search_plan : WebSearchPlanStructure
121
+ Generated search plan.
122
+ web_search_results : list[WebSearchItemResultStructure]
123
+ List of search results.
124
+ web_search_report : WebSearchReportStructure
125
+ Final synthesized report.
126
+
127
+ Methods
128
+ -------
129
+ print()
130
+ Return the markdown report.
131
+
132
+ Examples
133
+ --------
134
+ >>> workflow = WebSearchStructure(
135
+ ... query="Test query",
136
+ ... web_search_plan=WebSearchPlanStructure(searches=[]),
137
+ ... web_search_results=[],
138
+ ... web_search_report=WebSearchReportStructure(
139
+ ... short_summary="S",
140
+ ... markdown_report="R",
141
+ ... follow_up_questions=[],
142
+ ... sources=[]
143
+ ... )
144
+ ... )
145
+ """
40
146
 
41
147
  query: str = spec_field("query")
42
148
  web_search_plan: WebSearchPlanStructure = spec_field("web_search_plan")
43
- web_search_results: List[WebSearchItemResultStructure] = spec_field(
149
+ web_search_results: list[WebSearchItemResultStructure] = spec_field(
44
150
  "web_search_results"
45
151
  )
46
152
  web_search_report: WebSearchReportStructure = spec_field("web_search_report")
153
+
154
+ def print(self) -> str:
155
+ """Return the markdown report.
156
+
157
+ Returns
158
+ -------
159
+ str
160
+ Markdown-formatted report from web search results.
161
+ """
162
+ return self.web_search_report.markdown_report
@@ -0,0 +1,57 @@
1
+ """Common type definitions shared across the SDK.
2
+
3
+ This module defines protocol types and type aliases for OpenAI client
4
+ compatibility, enabling flexible client usage throughout the package.
5
+
6
+ Classes
7
+ -------
8
+ SupportsOpenAIClient
9
+ Protocol describing the subset of OpenAI client interface used by the SDK.
10
+
11
+ Type Aliases
12
+ ------------
13
+ OpenAIClient
14
+ Union type accepting OpenAI client or compatible protocol implementations.
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ from typing import Any, Protocol
20
+
21
+ from openai import OpenAI
22
+
23
+
24
+ class SupportsOpenAIClient(Protocol):
25
+ """Protocol describing the subset of the OpenAI client the SDK relies on.
26
+
27
+ Defines the minimum interface required for OpenAI client compatibility.
28
+ Custom implementations can satisfy this protocol for testing or
29
+ alternative backends.
30
+
31
+ Attributes
32
+ ----------
33
+ api_key : str or None
34
+ API key for authentication.
35
+ vector_stores : Any
36
+ Vector stores management interface.
37
+ responses : Any
38
+ Responses API interface.
39
+ files : Any
40
+ Files management interface.
41
+ """
42
+
43
+ api_key: str | None
44
+ vector_stores: Any
45
+ responses: Any
46
+ files: Any
47
+
48
+
49
+ OpenAIClient = OpenAI | SupportsOpenAIClient
50
+ """Type alias for OpenAI client or compatible protocol implementation.
51
+
52
+ Accepts either the official OpenAI client or any object satisfying the
53
+ SupportsOpenAIClient protocol.
54
+ """
55
+
56
+
57
+ __all__ = ["SupportsOpenAIClient", "OpenAIClient"]
@@ -1,10 +1,40 @@
1
- """Shared utility helpers for openai-sdk-helpers."""
1
+ """Utility helpers for openai-sdk-helpers.
2
+
3
+ This package provides common utility functions for type coercion, file
4
+ handling, JSON serialization, and logging. These utilities are used
5
+ throughout the openai_sdk_helpers package.
6
+
7
+ Functions
8
+ ---------
9
+ ensure_list(value)
10
+ Normalize a single item or iterable into a list.
11
+ check_filepath(filepath, fullfilepath)
12
+ Ensure the parent directory for a file path exists.
13
+ coerce_optional_float(value)
14
+ Convert a value to float or None.
15
+ coerce_optional_int(value)
16
+ Convert a value to int or None.
17
+ coerce_dict(value)
18
+ Convert a value to a string-keyed dictionary.
19
+ coerce_jsonable(value)
20
+ Convert a value into a JSON-serializable representation.
21
+ log(message, level)
22
+ Log a message with basic configuration.
23
+
24
+ Classes
25
+ -------
26
+ JSONSerializable
27
+ Mixin for classes that can be serialized to JSON.
28
+ customJSONEncoder
29
+ JSON encoder for common helper types like enums and paths.
30
+ """
2
31
 
3
32
  from __future__ import annotations
4
33
 
5
34
  from .core import (
6
35
  JSONSerializable,
7
36
  check_filepath,
37
+ coerce_jsonable,
8
38
  coerce_dict,
9
39
  coerce_optional_float,
10
40
  coerce_optional_int,
@@ -19,6 +49,7 @@ __all__ = [
19
49
  "coerce_optional_float",
20
50
  "coerce_optional_int",
21
51
  "coerce_dict",
52
+ "coerce_jsonable",
22
53
  "JSONSerializable",
23
54
  "customJSONEncoder",
24
55
  "log",