openai-sdk-helpers 0.4.1__tar.gz → 0.4.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/PKG-INFO +8 -8
  2. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/README.md +7 -7
  3. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/pyproject.toml +1 -1
  4. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/__init__.py +10 -36
  5. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/agent/__init__.py +5 -6
  6. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/agent/base.py +184 -39
  7. openai_sdk_helpers-0.4.1/src/openai_sdk_helpers/agent/config.py → openai_sdk_helpers-0.4.3/src/openai_sdk_helpers/agent/configuration.py +50 -75
  8. openai_sdk_helpers-0.4.1/src/openai_sdk_helpers/agent/coordination.py → openai_sdk_helpers-0.4.3/src/openai_sdk_helpers/agent/coordinator.py +12 -10
  9. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/agent/search/__init__.py +4 -4
  10. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/agent/search/base.py +16 -16
  11. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/agent/search/vector.py +66 -42
  12. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/agent/search/web.py +33 -29
  13. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/agent/summarizer.py +6 -4
  14. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/agent/translator.py +9 -5
  15. openai_sdk_helpers-0.4.1/src/openai_sdk_helpers/agent/validation.py → openai_sdk_helpers-0.4.3/src/openai_sdk_helpers/agent/validator.py +6 -4
  16. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/cli.py +8 -22
  17. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/environment.py +17 -0
  18. openai_sdk_helpers-0.4.3/src/openai_sdk_helpers/prompt/vector_planner.jinja +7 -0
  19. openai_sdk_helpers-0.4.3/src/openai_sdk_helpers/prompt/vector_search.jinja +6 -0
  20. openai_sdk_helpers-0.4.3/src/openai_sdk_helpers/prompt/vector_writer.jinja +7 -0
  21. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/response/__init__.py +1 -1
  22. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/response/base.py +4 -4
  23. openai_sdk_helpers-0.4.1/src/openai_sdk_helpers/response/config.py → openai_sdk_helpers-0.4.3/src/openai_sdk_helpers/response/configuration.py +9 -9
  24. openai_sdk_helpers-0.4.3/src/openai_sdk_helpers/response/planner.py +12 -0
  25. openai_sdk_helpers-0.4.3/src/openai_sdk_helpers/response/prompter.py +12 -0
  26. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/streamlit_app/__init__.py +1 -1
  27. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/streamlit_app/app.py +16 -17
  28. openai_sdk_helpers-0.4.1/src/openai_sdk_helpers/streamlit_app/config.py → openai_sdk_helpers-0.4.3/src/openai_sdk_helpers/streamlit_app/configuration.py +13 -13
  29. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/streamlit_app/streamlit_web_search.py +3 -3
  30. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/types.py +3 -3
  31. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/utils/__init__.py +2 -6
  32. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/utils/json/base_model.py +1 -1
  33. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/utils/json/data_class.py +1 -1
  34. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/utils/json/ref.py +3 -0
  35. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/utils/registry.py +19 -15
  36. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/vector_storage/storage.py +1 -1
  37. openai_sdk_helpers-0.4.1/src/openai_sdk_helpers/agent/prompt_utils.py +0 -15
  38. openai_sdk_helpers-0.4.1/src/openai_sdk_helpers/context_manager.py +0 -241
  39. openai_sdk_helpers-0.4.1/src/openai_sdk_helpers/deprecation.py +0 -167
  40. openai_sdk_helpers-0.4.1/src/openai_sdk_helpers/retry.py +0 -175
  41. openai_sdk_helpers-0.4.1/src/openai_sdk_helpers/utils/deprecation.py +0 -167
  42. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/.gitignore +0 -0
  43. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/LICENSE +0 -0
  44. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/agent/runner.py +0 -0
  45. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/agent/utils.py +0 -0
  46. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/enums/__init__.py +0 -0
  47. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/enums/base.py +0 -0
  48. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/errors.py +0 -0
  49. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/files_api.py +0 -0
  50. /openai_sdk_helpers-0.4.1/src/openai_sdk_helpers/logging_config.py → /openai_sdk_helpers-0.4.3/src/openai_sdk_helpers/logging.py +0 -0
  51. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/prompt/__init__.py +0 -0
  52. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/prompt/base.py +0 -0
  53. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/prompt/summarizer.jinja +0 -0
  54. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/prompt/translator.jinja +0 -0
  55. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/prompt/validator.jinja +0 -0
  56. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/py.typed +0 -0
  57. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/response/files.py +0 -0
  58. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/response/messages.py +0 -0
  59. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/response/runner.py +0 -0
  60. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/response/tool_call.py +0 -0
  61. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/response/vector_store.py +0 -0
  62. /openai_sdk_helpers-0.4.1/src/openai_sdk_helpers/config.py → /openai_sdk_helpers-0.4.3/src/openai_sdk_helpers/settings.py +0 -0
  63. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/structure/__init__.py +0 -0
  64. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/structure/agent_blueprint.py +0 -0
  65. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/structure/base.py +0 -0
  66. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/structure/plan/__init__.py +0 -0
  67. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/structure/plan/enum.py +0 -0
  68. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/structure/plan/helpers.py +0 -0
  69. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/structure/plan/plan.py +0 -0
  70. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/structure/plan/task.py +0 -0
  71. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/structure/plan/types.py +0 -0
  72. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/structure/prompt.py +0 -0
  73. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/structure/responses.py +0 -0
  74. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/structure/summary.py +0 -0
  75. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/structure/translation.py +0 -0
  76. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/structure/validation.py +0 -0
  77. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/structure/vector_search.py +0 -0
  78. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/structure/web_search.py +0 -0
  79. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/tools.py +0 -0
  80. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/utils/async_utils.py +0 -0
  81. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/utils/coercion.py +0 -0
  82. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/utils/encoding.py +0 -0
  83. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/utils/instructions.py +0 -0
  84. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/utils/json/__init__.py +0 -0
  85. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/utils/json/utils.py +0 -0
  86. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/utils/output_validation.py +0 -0
  87. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/utils/path_utils.py +0 -0
  88. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/utils/validation.py +0 -0
  89. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/vector_storage/__init__.py +0 -0
  90. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/vector_storage/cleanup.py +0 -0
  91. {openai_sdk_helpers-0.4.1 → openai_sdk_helpers-0.4.3}/src/openai_sdk_helpers/vector_storage/types.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openai-sdk-helpers
3
- Version: 0.4.1
3
+ Version: 0.4.3
4
4
  Summary: Composable helpers for OpenAI SDK agents, prompts, and storage
5
5
  Author: openai-sdk-helpers maintainers
6
6
  License: MIT
@@ -193,10 +193,11 @@ report = vector_search.run_agent_sync("Explain quantum entanglement for beginner
193
193
  print(report.report)
194
194
  ```
195
195
 
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`.
196
+ **Note**: The vector search workflow ships with default prompt templates
197
+ (`vector_planner.jinja`, `vector_search.jinja`, and `vector_writer.jinja`).
198
+ You only need to pass a `prompt_dir` when you want to override them; if the
199
+ directory you supply is missing any of the templates, agent construction will
200
+ fail with a `FileNotFoundError`.
200
201
 
201
202
  ### Text utilities
202
203
 
@@ -510,7 +511,7 @@ src/openai_sdk_helpers/
510
511
  │ ├── summary.py # Summary output structures
511
512
  │ └── validation.py # Validation result structures
512
513
  ├── vector_storage/ # Vector store abstraction layer
513
- ├── config.py # OpenAI settings and configuration
514
+ ├── configuration.py # OpenAI settings and configuration
514
515
  └── utils/ # JSON serialization, logging, and helpers
515
516
 
516
517
  tests/ # Comprehensive unit test suite
@@ -562,7 +563,7 @@ These modules use the standard `openai` SDK for direct API interactions with fin
562
563
 
563
564
  ### Configuration and Data Structures (Shared)
564
565
 
565
- - **`openai_sdk_helpers.config.OpenAISettings`**
566
+ - **`openai_sdk_helpers.settings.OpenAISettings`**
566
567
  Centralizes OpenAI API configuration with environment variable support.
567
568
  Creates configured OpenAI clients with consistent settings.
568
569
 
@@ -696,4 +697,3 @@ recognizing types:
696
697
  - Check the [Key Modules](#key-modules) section for API documentation
697
698
  - Review examples in the [Quickstart](#quickstart) and [Advanced Usage](#advanced-usage) sections
698
699
  - Open an issue on GitHub for bugs or feature requests
699
-
@@ -158,10 +158,11 @@ report = vector_search.run_agent_sync("Explain quantum entanglement for beginner
158
158
  print(report.report)
159
159
  ```
160
160
 
161
- **Note**: The vector search workflow requires prompt templates for each agent
162
- (`vector_planner.jinja`, `vector_search.jinja`, and `vector_writer.jinja`).
163
- If your `prompt_dir` doesn't contain these files, agent construction will fail
164
- with a `FileNotFoundError`.
161
+ **Note**: The vector search workflow ships with default prompt templates
162
+ (`vector_planner.jinja`, `vector_search.jinja`, and `vector_writer.jinja`).
163
+ You only need to pass a `prompt_dir` when you want to override them; if the
164
+ directory you supply is missing any of the templates, agent construction will
165
+ fail with a `FileNotFoundError`.
165
166
 
166
167
  ### Text utilities
167
168
 
@@ -475,7 +476,7 @@ src/openai_sdk_helpers/
475
476
  │ ├── summary.py # Summary output structures
476
477
  │ └── validation.py # Validation result structures
477
478
  ├── vector_storage/ # Vector store abstraction layer
478
- ├── config.py # OpenAI settings and configuration
479
+ ├── configuration.py # OpenAI settings and configuration
479
480
  └── utils/ # JSON serialization, logging, and helpers
480
481
 
481
482
  tests/ # Comprehensive unit test suite
@@ -527,7 +528,7 @@ These modules use the standard `openai` SDK for direct API interactions with fin
527
528
 
528
529
  ### Configuration and Data Structures (Shared)
529
530
 
530
- - **`openai_sdk_helpers.config.OpenAISettings`**
531
+ - **`openai_sdk_helpers.settings.OpenAISettings`**
531
532
  Centralizes OpenAI API configuration with environment variable support.
532
533
  Creates configured OpenAI clients with consistent settings.
533
534
 
@@ -661,4 +662,3 @@ recognizing types:
661
662
  - Check the [Key Modules](#key-modules) section for API documentation
662
663
  - Review examples in the [Quickstart](#quickstart) and [Advanced Usage](#advanced-usage) sections
663
664
  - Open an issue on GitHub for bugs or feature requests
664
-
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "openai-sdk-helpers"
3
- version = "0.4.1"
3
+ version = "0.4.3"
4
4
  requires-python = ">=3.10"
5
5
  readme = "README.md"
6
6
  description = "Composable helpers for OpenAI SDK agents, prompts, and storage"
@@ -2,14 +2,9 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ from .environment import get_data_path
5
6
  from .utils.async_utils import run_coroutine_thread_safe, run_coroutine_with_fallback
6
- from .context_manager import (
7
- AsyncManagedResource,
8
- ManagedResource,
9
- async_context,
10
- ensure_closed,
11
- ensure_closed_async,
12
- )
7
+
13
8
  from .errors import (
14
9
  OpenAISDKError,
15
10
  ConfigurationError,
@@ -22,7 +17,7 @@ from .errors import (
22
17
  AsyncExecutionError,
23
18
  ResourceCleanupError,
24
19
  )
25
- from .retry import with_exponential_backoff
20
+
26
21
  from .utils.validation import (
27
22
  validate_choice,
28
23
  validate_dict_mapping,
@@ -50,7 +45,7 @@ from .structure import (
50
45
  execute_plan,
51
46
  )
52
47
  from .prompt import PromptRenderer
53
- from .config import OpenAISettings
48
+ from .settings import OpenAISettings
54
49
  from .files_api import FilesAPIManager, FilePurpose
55
50
  from .vector_storage import VectorStorage, VectorStorageFileInfo, VectorStorageFileStats
56
51
  from .agent import (
@@ -61,7 +56,7 @@ from .agent import (
61
56
  SummarizerAgent,
62
57
  TranslatorAgent,
63
58
  ValidatorAgent,
64
- VectorSearch,
59
+ VectorAgentSearch,
65
60
  WebAgentSearch,
66
61
  )
67
62
  from .response import (
@@ -82,12 +77,7 @@ from .tools import (
82
77
  ToolSpec,
83
78
  build_tool_definitions,
84
79
  )
85
- from .config import build_openai_settings
86
- from .utils.deprecation import (
87
- deprecated,
88
- warn_deprecated,
89
- DeprecationHelper,
90
- )
80
+ from .settings import build_openai_settings
91
81
  from .utils.output_validation import (
92
82
  ValidationResult,
93
83
  ValidationRule,
@@ -97,12 +87,11 @@ from .utils.output_validation import (
97
87
  OutputValidator,
98
88
  validate_output,
99
89
  )
100
- from .types import (
101
- SupportsOpenAIClient,
102
- OpenAIClient,
103
- )
90
+
104
91
 
105
92
  __all__ = [
93
+ # Environment utilities
94
+ "get_data_path",
106
95
  # Async utilities
107
96
  "run_coroutine_thread_safe",
108
97
  "run_coroutine_with_fallback",
@@ -117,14 +106,6 @@ __all__ = [
117
106
  "InputValidationError",
118
107
  "AsyncExecutionError",
119
108
  "ResourceCleanupError",
120
- # Retry utilities
121
- "with_exponential_backoff",
122
- # Context managers
123
- "ManagedResource",
124
- "AsyncManagedResource",
125
- "ensure_closed",
126
- "ensure_closed_async",
127
- "async_context",
128
109
  # Validation
129
110
  "validate_non_empty_string",
130
111
  "validate_max_length",
@@ -156,7 +137,7 @@ __all__ = [
156
137
  "SummarizerAgent",
157
138
  "TranslatorAgent",
158
139
  "ValidatorAgent",
159
- "VectorSearch",
140
+ "VectorAgentSearch",
160
141
  "WebAgentSearch",
161
142
  "ExtendedSummaryStructure",
162
143
  "WebSearchStructure",
@@ -180,13 +161,6 @@ __all__ = [
180
161
  "create_plan",
181
162
  "execute_task",
182
163
  "execute_plan",
183
- # Type definitions
184
- "SupportsOpenAIClient",
185
- "OpenAIClient",
186
- # Deprecation utilities
187
- "deprecated",
188
- "warn_deprecated",
189
- "DeprecationHelper",
190
164
  # Output validation
191
165
  "ValidationResult",
192
166
  "ValidationRule",
@@ -1,18 +1,17 @@
1
1
  """Shared agent helpers built on the OpenAI Agents SDK."""
2
2
 
3
3
  from __future__ import annotations
4
-
5
4
  from .base import AgentBase
6
- from .config import AgentConfiguration, AgentRegistry, get_default_registry
5
+ from .configuration import AgentConfiguration, AgentRegistry, get_default_registry
7
6
  from ..structure.plan.enum import AgentEnum
8
- from .coordination import CoordinatorAgent
7
+ from .coordinator import CoordinatorAgent
9
8
  from .runner import run_sync, run_async, run_streamed
10
9
  from .search.base import SearchPlanner, SearchToolAgent, SearchWriter
11
10
  from .summarizer import SummarizerAgent
12
11
  from .translator import TranslatorAgent
13
- from .validation import ValidatorAgent
12
+ from .validator import ValidatorAgent
14
13
  from .utils import run_coroutine_agent_sync
15
- from .search.vector import VectorSearch
14
+ from .search.vector import VectorAgentSearch
16
15
  from .search.web import WebAgentSearch
17
16
 
18
17
  __all__ = [
@@ -32,6 +31,6 @@ __all__ = [
32
31
  "SummarizerAgent",
33
32
  "TranslatorAgent",
34
33
  "ValidatorAgent",
35
- "VectorSearch",
34
+ "VectorAgentSearch",
36
35
  "WebAgentSearch",
37
36
  ]
@@ -2,8 +2,9 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import json
5
6
  from pathlib import Path
6
- from typing import Any, Callable, Dict, Optional, Protocol, cast
7
+ from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Protocol, cast
7
8
  import uuid
8
9
 
9
10
  from agents import (
@@ -21,14 +22,22 @@ from jinja2 import Template
21
22
 
22
23
  from ..utils.json.data_class import DataclassJSONSerializable
23
24
  from ..structure.base import StructureBase
25
+ from ..structure.prompt import PromptStructure
26
+
24
27
 
25
28
  from ..utils import (
26
29
  check_filepath,
27
30
  log,
28
31
  )
29
32
 
33
+ from ..tools import tool_handler_factory
34
+
30
35
  from .runner import run_async, run_streamed, run_sync
31
36
 
37
+ if TYPE_CHECKING:
38
+ from ..settings import OpenAISettings
39
+ from ..response.base import ResponseBase, ToolHandler
40
+
32
41
 
33
42
  class AgentConfigurationProtocol(Protocol):
34
43
  """Protocol describing the configuration attributes for AgentBase."""
@@ -122,22 +131,22 @@ class AgentBase(DataclassJSONSerializable):
122
131
  Create a basic agent from configuration:
123
132
 
124
133
  >>> from openai_sdk_helpers.agent import AgentBase, AgentConfiguration
125
- >>> config = AgentConfiguration(
134
+ >>> configuration = AgentConfiguration(
126
135
  ... name="my_agent",
127
136
  ... description="A custom agent",
128
137
  ... model="gpt-4o-mini"
129
138
  ... )
130
- >>> agent = AgentBase(config=config, default_model="gpt-4o-mini")
139
+ >>> agent = AgentBase(configuration=configuration, default_model="gpt-4o-mini")
131
140
  >>> result = agent.run_sync("What is 2+2?")
132
141
 
133
142
  Use absolute path to template:
134
143
 
135
- >>> config = AgentConfiguration(
144
+ >>> configuration = AgentConfiguration(
136
145
  ... name="my_agent",
137
146
  ... template_path="/absolute/path/to/template.jinja",
138
147
  ... model="gpt-4o-mini"
139
148
  ... )
140
- >>> agent = AgentBase(config=config, default_model="gpt-4o-mini")
149
+ >>> agent = AgentBase(configuration=configuration, default_model="gpt-4o-mini")
141
150
 
142
151
  Use async execution:
143
152
 
@@ -181,6 +190,10 @@ class AgentBase(DataclassJSONSerializable):
181
190
  Return a streaming result for the agent execution.
182
191
  as_tool()
183
192
  Return the agent as a callable tool.
193
+ as_response_tool()
194
+ Return response tool handler and definition for Responses API use.
195
+ build_response(openai_settings, data_path=None, tool_handlers=None, system_vector_store=None)
196
+ Build a ResponseBase instance based on this agent.
184
197
  close()
185
198
  Clean up agent resources (can be overridden by subclasses).
186
199
  """
@@ -188,7 +201,7 @@ class AgentBase(DataclassJSONSerializable):
188
201
  def __init__(
189
202
  self,
190
203
  *,
191
- config: AgentConfigurationProtocol,
204
+ configuration: AgentConfigurationProtocol,
192
205
  run_context_wrapper: Optional[RunContextWrapper[Dict[str, Any]]] = None,
193
206
  data_path: Path | str | None = None,
194
207
  prompt_dir: Optional[Path] = None,
@@ -198,29 +211,29 @@ class AgentBase(DataclassJSONSerializable):
198
211
 
199
212
  Parameters
200
213
  ----------
201
- config : AgentConfigurationProtocol
214
+ configuration : AgentConfigurationProtocol
202
215
  Configuration describing this agent.
203
216
  run_context_wrapper : RunContextWrapper or None, default=None
204
217
  Optional wrapper providing runtime context for prompt rendering.
205
218
  prompt_dir : Path or None, default=None
206
219
  Optional directory holding prompt templates. Used when
207
- ``config.template_path`` is not provided or is relative. If
208
- ``config.template_path`` is an absolute path, this parameter is
220
+ ``configuration.template_path`` is not provided or is relative. If
221
+ ``configuration.template_path`` is an absolute path, this parameter is
209
222
  ignored.
210
223
  default_model : str or None, default=None
211
- Optional fallback model identifier if the config does not supply one.
224
+ Optional fallback model identifier if the configuration does not supply one.
212
225
  """
213
- name = config.name
214
- description = config.description or ""
215
- model = config.model or default_model
226
+ name = configuration.name
227
+ description = configuration.description or ""
228
+ model = configuration.model or default_model
216
229
  if not model:
217
230
  raise ValueError("Model is required to construct the agent.")
218
231
 
219
- prompt_path = config.resolve_prompt_path(prompt_dir)
232
+ prompt_path = configuration.resolve_prompt_path(prompt_dir)
220
233
 
221
234
  # Build template from file or fall back to instructions
222
235
  if prompt_path is None:
223
- instructions_text = config.instructions_text
236
+ instructions_text = configuration.instructions_text
224
237
  self._template = Template(instructions_text)
225
238
  self._instructions = instructions_text
226
239
  elif prompt_path.exists():
@@ -249,14 +262,16 @@ class AgentBase(DataclassJSONSerializable):
249
262
 
250
263
  self._data_path = get_data_path(self.__class__.__name__)
251
264
 
252
- self._input_structure = config.input_structure
253
- self._output_structure = config.output_structure or config.input_structure
254
- self._tools = config.tools
255
- self._model_settings = config.model_settings
256
- self._handoffs = config.handoffs
257
- self._input_guardrails = config.input_guardrails
258
- self._output_guardrails = config.output_guardrails
259
- self._session = config.session
265
+ self._input_structure = configuration.input_structure
266
+ self._output_structure = (
267
+ configuration.output_structure or configuration.input_structure
268
+ )
269
+ self._tools = configuration.tools
270
+ self._model_settings = configuration.model_settings
271
+ self._handoffs = configuration.handoffs
272
+ self._input_guardrails = configuration.input_guardrails
273
+ self._output_guardrails = configuration.output_guardrails
274
+ self._session = configuration.session
260
275
  self._run_context_wrapper = run_context_wrapper
261
276
 
262
277
  def _build_prompt_from_jinja(self) -> str:
@@ -462,7 +477,7 @@ class AgentBase(DataclassJSONSerializable):
462
477
  Optional type used to cast the final output.
463
478
  session : Session or None, default=None
464
479
  Optional session for maintaining conversation history across runs.
465
- If not provided, uses the session from config if available.
480
+ If not provided, uses the session from configuration if available.
466
481
 
467
482
  Returns
468
483
  -------
@@ -471,7 +486,7 @@ class AgentBase(DataclassJSONSerializable):
471
486
  """
472
487
  if self._output_structure is not None and output_structure is None:
473
488
  output_structure = self._output_structure
474
- # Use session from parameter, fall back to config session
489
+ # Use session from parameter, fall back to configuration session
475
490
  session_to_use = session if session is not None else self._session
476
491
  return await run_async(
477
492
  agent=self.get_agent(),
@@ -501,7 +516,7 @@ class AgentBase(DataclassJSONSerializable):
501
516
  Optional type used to cast the final output.
502
517
  session : Session or None, default=None
503
518
  Optional session for maintaining conversation history across runs.
504
- If not provided, uses the session from config if available.
519
+ If not provided, uses the session from configuration if available.
505
520
 
506
521
  Returns
507
522
  -------
@@ -510,7 +525,7 @@ class AgentBase(DataclassJSONSerializable):
510
525
  """
511
526
  if self._output_structure is not None and output_structure is None:
512
527
  output_structure = self._output_structure
513
- # Use session from parameter, fall back to config session
528
+ # Use session from parameter, fall back to configuration session
514
529
  session_to_use = session if session is not None else self._session
515
530
  return run_sync(
516
531
  agent=self.get_agent(),
@@ -540,14 +555,14 @@ class AgentBase(DataclassJSONSerializable):
540
555
  Optional type used to cast the final output.
541
556
  session : Session or None, default=None
542
557
  Optional session for maintaining conversation history across runs.
543
- If not provided, uses the session from config if available.
558
+ If not provided, uses the session from configuration if available.
544
559
 
545
560
  Returns
546
561
  -------
547
562
  RunResultStreaming
548
563
  Streaming output wrapper from the agent execution.
549
564
  """
550
- # Use session from parameter, fall back to config session
565
+ # Use session from parameter, fall back to configuration session
551
566
  session_to_use = session if session is not None else self._session
552
567
  output_structure_to_use = output_structure or self._output_structure
553
568
  result = run_streamed(
@@ -575,26 +590,156 @@ class AgentBase(DataclassJSONSerializable):
575
590
  )
576
591
  return tool_obj
577
592
 
578
- def as_response_tool(self) -> tuple[dict[str, Callable[..., Any]], dict[str, Any]]:
579
- """Return the agent as a callable response tool.
593
+ def as_response_tool(
594
+ self,
595
+ *,
596
+ tool_name: str | None = None,
597
+ tool_description: str | None = None,
598
+ ) -> tuple[dict[str, Callable[..., Any]], dict[str, Any]]:
599
+ """Return response tool handler and definition for Responses API use.
600
+
601
+ The returned handler serializes tool output as JSON using
602
+ ``tool_handler_factory`` so downstream response flows can rely on a
603
+ consistent payload format.
604
+
605
+ Parameters
606
+ ----------
607
+ tool_name : str or None, default=None
608
+ Optional override for the tool name. When None, uses the agent name.
609
+ tool_description : str or None, default=None
610
+ Optional override for the tool description. When None, uses the
611
+ agent description.
580
612
 
581
613
  Returns
582
614
  -------
583
- Tool
584
- Tool instance wrapping this agent for response generation.
615
+ tuple[dict[str, Callable[..., Any]], dict[str, Any]]
616
+ Tool handler mapping and tool definition for Responses API usage.
617
+
618
+ Examples
619
+ --------
620
+ >>> tool_handler, tool_definition = agent.as_response_tool()
621
+ >>> response = ResponseBase(
622
+ ... name="agent_tool",
623
+ ... instructions="Use the agent tool when needed.",
624
+ ... tools=[tool_definition],
625
+ ... output_structure=None,
626
+ ... tool_handlers=tool_handler,
627
+ ... openai_settings=settings,
628
+ ... )
629
+ >>> response.run_sync("Invoke the agent tool") # doctest: +SKIP
585
630
  """
586
- tool_handler = {self.name: self.run_sync}
631
+
632
+ def _run_agent(**kwargs: Any) -> Any:
633
+ prompt = kwargs.get("prompt")
634
+ if prompt is None:
635
+ if len(kwargs) == 1:
636
+ prompt = next(iter(kwargs.values()))
637
+ else:
638
+ prompt = json.dumps(kwargs)
639
+ return self.run_sync(str(prompt))
640
+
641
+ name = tool_name or self.name
642
+ description = tool_description or self.description
643
+ input_model = self._input_structure or PromptStructure
644
+ tool_handler = {name: tool_handler_factory(_run_agent, input_model=input_model)}
587
645
  tool_definition = {
588
646
  "type": "function",
589
- "name": self.name,
590
- "description": self.description,
647
+ "name": name,
648
+ "description": description,
591
649
  "strict": True,
592
650
  "additionalProperties": False,
651
+ "parameters": self._build_response_parameters(),
593
652
  }
594
- if self.output_structure:
595
- tool_definition["parameters"] = self.output_structure.get_schema()
596
653
  return tool_handler, tool_definition
597
654
 
655
+ def build_response(
656
+ self,
657
+ *,
658
+ openai_settings: OpenAISettings,
659
+ data_path: Path | str | None = None,
660
+ tool_handlers: dict[str, ToolHandler] | None = None,
661
+ system_vector_store: list[str] | None = None,
662
+ ) -> ResponseBase[StructureBase]:
663
+ """Build a ResponseBase instance from this agent configuration.
664
+
665
+ Parameters
666
+ ----------
667
+ openai_settings : OpenAISettings
668
+ Authentication and model settings applied to the generated response.
669
+ data_path : Path, str, or None, default None
670
+ Optional path for storing response artifacts. When None, the
671
+ response uses the default data directory.
672
+ tool_handlers : dict[str, ToolHandler] or None, default None
673
+ Optional mapping of tool names to handler callables.
674
+ system_vector_store : list[str] or None, default None
675
+ Optional list of vector store names to attach as system context.
676
+
677
+ Returns
678
+ -------
679
+ ResponseBase[StructureBase]
680
+ ResponseBase instance configured with this agent's settings.
681
+
682
+ Examples
683
+ --------
684
+ >>> from openai_sdk_helpers import OpenAISettings
685
+ >>> response = agent.build_response(openai_settings=OpenAISettings.from_env())
686
+ """
687
+ from ..response.base import ResponseBase, ToolHandler
688
+ from ..settings import OpenAISettings
689
+
690
+ if not isinstance(openai_settings, OpenAISettings):
691
+ raise TypeError("openai_settings must be an OpenAISettings instance")
692
+
693
+ tools = self._normalize_response_tools(self.tools)
694
+
695
+ return ResponseBase(
696
+ name=self.name,
697
+ instructions=self.instructions_text,
698
+ tools=tools,
699
+ output_structure=self.output_structure,
700
+ system_vector_store=system_vector_store,
701
+ data_path=data_path,
702
+ tool_handlers=tool_handlers,
703
+ openai_settings=openai_settings,
704
+ )
705
+
706
+ def _build_response_parameters(self) -> dict[str, Any]:
707
+ """Build the Responses API parameter schema for this agent tool.
708
+
709
+ Returns
710
+ -------
711
+ dict[str, Any]
712
+ JSON schema describing tool input parameters.
713
+ """
714
+ if self._input_structure is not None:
715
+ return self._input_structure.get_schema()
716
+ return {
717
+ "type": "object",
718
+ "properties": {
719
+ "prompt": {"type": "string", "description": "Prompt text to run."}
720
+ },
721
+ "required": ["prompt"],
722
+ "additionalProperties": False,
723
+ }
724
+
725
+ @staticmethod
726
+ def _normalize_response_tools(tools: Optional[list]) -> Optional[list]:
727
+ """Normalize tool definitions for the Responses API."""
728
+ if not tools:
729
+ return tools
730
+
731
+ normalized: list[Any] = []
732
+ for tool in tools:
733
+ if hasattr(tool, "to_dict") and callable(tool.to_dict):
734
+ normalized.append(tool.to_dict())
735
+ elif hasattr(tool, "to_openai_tool") and callable(tool.to_openai_tool):
736
+ normalized.append(tool.to_openai_tool())
737
+ elif hasattr(tool, "schema"):
738
+ normalized.append(tool.schema)
739
+ else:
740
+ normalized.append(tool)
741
+ return normalized
742
+
598
743
  def __enter__(self) -> AgentBase:
599
744
  """Enter the context manager for resource management.
600
745
 
@@ -628,7 +773,7 @@ class AgentBase(DataclassJSONSerializable):
628
773
 
629
774
  Examples
630
775
  --------
631
- >>> agent = AgentBase(config, default_model="gpt-4o-mini")
776
+ >>> agent = AgentBase(configuration, default_model="gpt-4o-mini")
632
777
  >>> try:
633
778
  ... result = agent.run_sync("query")
634
779
  ... finally: