openai-sdk-helpers 0.1.4__tar.gz → 0.3.0__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 (83) hide show
  1. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/PKG-INFO +1 -1
  2. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/pyproject.toml +1 -1
  3. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/__init__.py +4 -4
  4. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/agent/__init__.py +6 -4
  5. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/agent/base.py +211 -47
  6. openai_sdk_helpers-0.3.0/src/openai_sdk_helpers/agent/config.py +375 -0
  7. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/agent/coordination.py +15 -6
  8. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/agent/runner.py +13 -4
  9. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/agent/search/base.py +17 -17
  10. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/agent/search/vector.py +13 -10
  11. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/agent/search/web.py +13 -10
  12. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/agent/summarizer.py +5 -4
  13. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/agent/translator.py +5 -4
  14. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/agent/validation.py +5 -4
  15. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/response/base.py +84 -8
  16. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/response/config.py +28 -110
  17. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/response/messages.py +16 -0
  18. openai_sdk_helpers-0.3.0/src/openai_sdk_helpers/utils/instructions.py +35 -0
  19. openai_sdk_helpers-0.3.0/src/openai_sdk_helpers/utils/json_utils.py +230 -0
  20. openai_sdk_helpers-0.3.0/src/openai_sdk_helpers/utils/registry.py +183 -0
  21. openai_sdk_helpers-0.1.4/src/openai_sdk_helpers/agent/config.py +0 -68
  22. openai_sdk_helpers-0.1.4/src/openai_sdk_helpers/utils/json_utils.py +0 -98
  23. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/.gitignore +0 -0
  24. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/LICENSE +0 -0
  25. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/README.md +0 -0
  26. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/agent/prompt_utils.py +0 -0
  27. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/agent/search/__init__.py +0 -0
  28. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/agent/utils.py +0 -0
  29. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/cli.py +0 -0
  30. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/config.py +0 -0
  31. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/context_manager.py +0 -0
  32. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/deprecation.py +0 -0
  33. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/enums/__init__.py +0 -0
  34. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/enums/base.py +0 -0
  35. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/environment.py +0 -0
  36. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/errors.py +0 -0
  37. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/files_api.py +0 -0
  38. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/logging_config.py +0 -0
  39. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/prompt/__init__.py +0 -0
  40. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/prompt/base.py +0 -0
  41. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/prompt/summarizer.jinja +0 -0
  42. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/prompt/translator.jinja +0 -0
  43. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/prompt/validator.jinja +0 -0
  44. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/py.typed +0 -0
  45. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/response/__init__.py +0 -0
  46. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/response/files.py +0 -0
  47. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/response/runner.py +0 -0
  48. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/response/tool_call.py +0 -0
  49. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/response/vector_store.py +0 -0
  50. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/retry.py +0 -0
  51. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/streamlit_app/__init__.py +0 -0
  52. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/streamlit_app/app.py +0 -0
  53. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/streamlit_app/config.py +0 -0
  54. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/streamlit_app/streamlit_web_search.py +0 -0
  55. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/structure/__init__.py +0 -0
  56. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/structure/agent_blueprint.py +0 -0
  57. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/structure/base.py +0 -0
  58. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/structure/plan/__init__.py +0 -0
  59. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/structure/plan/enum.py +0 -0
  60. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/structure/plan/helpers.py +0 -0
  61. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/structure/plan/plan.py +0 -0
  62. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/structure/plan/task.py +0 -0
  63. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/structure/plan/types.py +0 -0
  64. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/structure/prompt.py +0 -0
  65. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/structure/responses.py +0 -0
  66. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/structure/summary.py +0 -0
  67. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/structure/validation.py +0 -0
  68. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/structure/vector_search.py +0 -0
  69. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/structure/web_search.py +0 -0
  70. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/tools.py +0 -0
  71. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/types.py +0 -0
  72. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/utils/__init__.py +0 -0
  73. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/utils/async_utils.py +0 -0
  74. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/utils/coercion.py +0 -0
  75. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/utils/deprecation.py +0 -0
  76. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/utils/encoding.py +0 -0
  77. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/utils/output_validation.py +0 -0
  78. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/utils/path_utils.py +0 -0
  79. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/utils/validation.py +0 -0
  80. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/vector_storage/__init__.py +0 -0
  81. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/vector_storage/cleanup.py +0 -0
  82. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/src/openai_sdk_helpers/vector_storage/storage.py +0 -0
  83. {openai_sdk_helpers-0.1.4 → openai_sdk_helpers-0.3.0}/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.1.4
3
+ Version: 0.3.0
4
4
  Summary: Composable helpers for OpenAI SDK agents, prompts, and storage
5
5
  Author: openai-sdk-helpers maintainers
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "openai-sdk-helpers"
3
- version = "0.1.4"
3
+ version = "0.3.0"
4
4
  requires-python = ">=3.10"
5
5
  readme = "README.md"
6
6
  description = "Composable helpers for OpenAI SDK agents, prompts, and storage"
@@ -54,8 +54,8 @@ from .config import OpenAISettings
54
54
  from .files_api import FilesAPIManager, FilePurpose
55
55
  from .vector_storage import VectorStorage, VectorStorageFileInfo, VectorStorageFileStats
56
56
  from .agent import (
57
- AgentBase,
58
- AgentConfig,
57
+ BaseAgent,
58
+ AgentConfiguration,
59
59
  AgentEnum,
60
60
  CoordinatorAgent,
61
61
  SummarizerAgent,
@@ -150,8 +150,8 @@ __all__ = [
150
150
  "TaskStructure",
151
151
  "PlanStructure",
152
152
  "AgentEnum",
153
- "AgentBase",
154
- "AgentConfig",
153
+ "BaseAgent",
154
+ "AgentConfiguration",
155
155
  "CoordinatorAgent",
156
156
  "SummarizerAgent",
157
157
  "TranslatorAgent",
@@ -2,8 +2,8 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from .base import AgentBase
6
- from .config import AgentConfig
5
+ from .base import BaseAgent
6
+ from .config import AgentConfiguration, AgentConfigurationRegistry, get_default_registry
7
7
  from ..structure.plan.enum import AgentEnum
8
8
  from .coordination import CoordinatorAgent
9
9
  from .runner import run_sync, run_async, run_streamed
@@ -16,8 +16,10 @@ from .search.vector import VectorSearch
16
16
  from .search.web import WebAgentSearch
17
17
 
18
18
  __all__ = [
19
- "AgentBase",
20
- "AgentConfig",
19
+ "BaseAgent",
20
+ "AgentConfiguration",
21
+ "AgentConfigurationRegistry",
22
+ "get_default_registry",
21
23
  "AgentEnum",
22
24
  "CoordinatorAgent",
23
25
  "run_sync",
@@ -5,56 +5,128 @@ from __future__ import annotations
5
5
  from pathlib import Path
6
6
  from typing import Any, Dict, Optional, Protocol
7
7
 
8
- from agents import Agent, RunResult, RunResultStreaming, Runner
8
+ from agents import (
9
+ Agent,
10
+ Handoff,
11
+ InputGuardrail,
12
+ OutputGuardrail,
13
+ RunResult,
14
+ RunResultStreaming,
15
+ Runner,
16
+ Session,
17
+ )
18
+ from agents.model_settings import ModelSettings
9
19
  from agents.run_context import RunContextWrapper
10
- from agents.tool import FunctionTool
20
+ from agents.tool import Tool
11
21
  from jinja2 import Template
12
22
 
13
23
  from .runner import run_async, run_streamed, run_sync
14
24
 
15
25
 
16
- class AgentConfigLike(Protocol):
17
- """Protocol describing the configuration attributes for AgentBase."""
18
-
19
- name: str
20
- description: Optional[str]
21
- model: Optional[str]
22
- template_path: Optional[str]
23
- input_type: Optional[Any]
24
- output_type: Optional[Any]
25
- tools: Optional[Any]
26
- model_settings: Optional[Any]
27
-
28
-
29
- class AgentBase:
26
+ class AgentConfigurationLike(Protocol):
27
+ """Protocol describing the configuration attributes for BaseAgent."""
28
+
29
+ @property
30
+ def name(self) -> str:
31
+ """Agent name."""
32
+ ...
33
+
34
+ @property
35
+ def description(self) -> Optional[str]:
36
+ """Agent description."""
37
+ ...
38
+
39
+ @property
40
+ def model(self) -> Optional[str]:
41
+ """Model identifier."""
42
+ ...
43
+
44
+ @property
45
+ def template_path(self) -> Optional[str | Path]:
46
+ """Template path."""
47
+ ...
48
+
49
+ @property
50
+ def instructions(self) -> str | Path:
51
+ """Instructions."""
52
+ ...
53
+
54
+ @property
55
+ def instructions_text(self) -> str:
56
+ """Resolved instructions text."""
57
+ ...
58
+
59
+ @property
60
+ def input_type(self) -> Optional[type]:
61
+ """Input type."""
62
+ ...
63
+
64
+ @property
65
+ def output_type(self) -> Optional[type]:
66
+ """Output type."""
67
+ ...
68
+
69
+ @property
70
+ def tools(self) -> Optional[list]:
71
+ """Tools."""
72
+ ...
73
+
74
+ @property
75
+ def model_settings(self) -> Optional[ModelSettings]:
76
+ """Model settings."""
77
+ ...
78
+
79
+ @property
80
+ def handoffs(self) -> Optional[list[Agent | Handoff]]:
81
+ """Handoffs."""
82
+ ...
83
+
84
+ @property
85
+ def input_guardrails(self) -> Optional[list[InputGuardrail]]:
86
+ """Input guardrails."""
87
+ ...
88
+
89
+ @property
90
+ def output_guardrails(self) -> Optional[list[OutputGuardrail]]:
91
+ """Output guardrails."""
92
+ ...
93
+
94
+ @property
95
+ def session(self) -> Optional[Session]:
96
+ """Session."""
97
+ ...
98
+
99
+
100
+ class BaseAgent:
30
101
  """Factory for creating and configuring specialized agents.
31
102
 
32
- ``AgentBase`` provides the foundation for building OpenAI agents with support
33
- for Jinja2 prompt templates, custom tools, and both synchronous and
34
- asynchronous execution modes. All specialized agents in this package extend
35
- this base class.
103
+ ``BaseAgent`` provides the foundation for building OpenAI agents with support
104
+ for Jinja2 prompt templates, custom tools, handoffs for agent delegation,
105
+ input and output guardrails for validation, session management for
106
+ conversation history, and both synchronous and asynchronous execution modes.
107
+ All specialized agents in this package extend this base class.
36
108
 
37
109
  Examples
38
110
  --------
39
111
  Create a basic agent from configuration:
40
112
 
41
- >>> from openai_sdk_helpers.agent import AgentBase, AgentConfig
42
- >>> config = AgentConfig(
113
+ >>> from openai_sdk_helpers.agent import BaseAgent, AgentConfiguration
114
+ >>> config = AgentConfiguration(
43
115
  ... name="my_agent",
44
116
  ... description="A custom agent",
45
117
  ... model="gpt-4o-mini"
46
118
  ... )
47
- >>> agent = AgentBase(config=config, default_model="gpt-4o-mini")
119
+ >>> agent = BaseAgent(config=config, default_model="gpt-4o-mini")
48
120
  >>> result = agent.run_sync("What is 2+2?")
49
121
 
50
122
  Use absolute path to template:
51
123
 
52
- >>> config = AgentConfig(
124
+ >>> config = AgentConfiguration(
53
125
  ... name="my_agent",
54
126
  ... template_path="/absolute/path/to/template.jinja",
55
127
  ... model="gpt-4o-mini"
56
128
  ... )
57
- >>> agent = AgentBase(config=config, default_model="gpt-4o-mini")
129
+ >>> agent = BaseAgent(config=config, default_model="gpt-4o-mini")
58
130
 
59
131
  Use async execution:
60
132
 
@@ -66,38 +138,38 @@ class AgentBase:
66
138
 
67
139
  Methods
68
140
  -------
69
- from_config(config, run_context_wrapper)
70
- Instantiate a ``AgentBase`` from configuration.
141
+ from_configuration(config, run_context_wrapper, prompt_dir, default_model)
142
+ Instantiate a ``BaseAgent`` from configuration.
71
143
  build_prompt_from_jinja(run_context_wrapper)
72
144
  Render the agent prompt using Jinja and optional context.
73
145
  get_prompt(run_context_wrapper, _)
74
146
  Render the agent prompt using the provided run context.
75
147
  get_agent()
76
148
  Construct the configured :class:`agents.Agent` instance.
77
- run(input, context, output_type)
78
- Execute the agent asynchronously (alias of ``run_async``).
79
- run_async(input, context, output_type)
149
+ run_async(input, context, output_type, session)
80
150
  Execute the agent asynchronously and optionally cast the result.
81
- run_sync(input, context, output_type)
151
+ run_sync(input, context, output_type, session)
82
152
  Execute the agent synchronously.
83
- run_streamed(input, context, output_type)
153
+ run_streamed(input, context, output_type, session)
84
154
  Return a streaming result for the agent execution.
85
155
  as_tool()
86
156
  Return the agent as a callable tool.
157
+ close()
158
+ Clean up agent resources (can be overridden by subclasses).
87
159
  """
88
160
 
89
161
  def __init__(
90
162
  self,
91
- config: AgentConfigLike,
163
+ config: AgentConfigurationLike,
92
164
  run_context_wrapper: Optional[RunContextWrapper[Dict[str, Any]]] = None,
93
165
  prompt_dir: Optional[Path] = None,
94
166
  default_model: Optional[str] = None,
95
167
  ) -> None:
96
- """Initialize the AgentBase using a configuration object.
168
+ """Initialize the BaseAgent using a configuration object.
97
169
 
98
170
  Parameters
99
171
  ----------
100
- config : AgentConfigLike
172
+ config : AgentConfigurationLike
101
173
  Configuration describing this agent.
102
174
  run_context_wrapper : RunContextWrapper or None, default=None
103
175
  Optional wrapper providing runtime context for prompt rendering.
@@ -123,8 +195,24 @@ class AgentBase:
123
195
  else:
124
196
  prompt_path = None
125
197
 
198
+ # Build template from file or fall back to instructions
126
199
  if prompt_path is None:
127
- self._template = Template("")
200
+ # No template path - use instructions (always available now)
201
+ if hasattr(config, "instructions_text"):
202
+ # AgentConfiguration has this property - use it for proper resolution
203
+ instructions_text = config.instructions_text
204
+ else:
205
+ # Fall back to resolving instructions ourselves
206
+ if isinstance(config.instructions, Path):
207
+ try:
208
+ instructions_text = config.instructions.read_text(
209
+ encoding="utf-8"
210
+ )
211
+ except OSError:
212
+ instructions_text = "" # Leave empty if file can't be read
213
+ else:
214
+ instructions_text = config.instructions
215
+ self._template = Template(instructions_text)
128
216
  elif prompt_path.exists():
129
217
  self._template = Template(prompt_path.read_text())
130
218
  else:
@@ -140,22 +228,29 @@ class AgentBase:
140
228
  self._output_type = config.output_type or config.input_type
141
229
  self._tools = config.tools
142
230
  self._model_settings = config.model_settings
231
+ self._handoffs = config.handoffs
232
+ self._input_guardrails = config.input_guardrails
233
+ self._output_guardrails = config.output_guardrails
234
+ self._session = config.session
143
235
  self._run_context_wrapper = run_context_wrapper
144
236
 
237
+ # Store instructions if provided directly in config
238
+ self._instructions = getattr(config, "instructions", None)
239
+
145
240
  @classmethod
146
- def from_config(
241
+ def from_configuration(
147
242
  cls,
148
- config: AgentConfigLike,
243
+ config: AgentConfigurationLike,
149
244
  *,
150
245
  run_context_wrapper: Optional[RunContextWrapper[Dict[str, Any]]] = None,
151
246
  prompt_dir: Optional[Path] = None,
152
247
  default_model: Optional[str] = None,
153
- ) -> AgentBase:
154
- """Create an AgentBase instance from configuration.
248
+ ) -> BaseAgent:
249
+ """Create a BaseAgent instance from configuration.
155
250
 
156
251
  Parameters
157
252
  ----------
158
- config : AgentConfigLike
253
+ config : AgentConfigurationLike
159
254
  Configuration describing the agent.
160
255
  run_context_wrapper : RunContextWrapper or None, default=None
161
256
  Optional wrapper providing runtime context.
@@ -169,7 +264,7 @@ class AgentBase:
169
264
 
170
265
  Returns
171
266
  -------
172
- AgentBase
267
+ BaseAgent
173
268
  Instantiated agent.
174
269
  """
175
270
  return cls(
@@ -252,6 +347,12 @@ class AgentBase:
252
347
  agent_config["tools"] = self._tools
253
348
  if self._model_settings:
254
349
  agent_config["model_settings"] = self._model_settings
350
+ if self._handoffs:
351
+ agent_config["handoffs"] = self._handoffs
352
+ if self._input_guardrails:
353
+ agent_config["input_guardrails"] = self._input_guardrails
354
+ if self._output_guardrails:
355
+ agent_config["output_guardrails"] = self._output_guardrails
255
356
 
256
357
  return Agent(**agent_config)
257
358
 
@@ -261,6 +362,7 @@ class AgentBase:
261
362
  *,
262
363
  context: Optional[Dict[str, Any]] = None,
263
364
  output_type: Optional[Any] = None,
365
+ session: Optional[Any] = None,
264
366
  ) -> Any:
265
367
  """Execute the agent asynchronously.
266
368
 
@@ -272,6 +374,9 @@ class AgentBase:
272
374
  Optional dictionary passed to the agent.
273
375
  output_type : type or None, default=None
274
376
  Optional type used to cast the final output.
377
+ session : Session or None, default=None
378
+ Optional session for maintaining conversation history across runs.
379
+ If not provided, uses the session from config if available.
275
380
 
276
381
  Returns
277
382
  -------
@@ -280,11 +385,14 @@ class AgentBase:
280
385
  """
281
386
  if self._output_type is not None and output_type is None:
282
387
  output_type = self._output_type
388
+ # Use session from parameter, fall back to config session
389
+ session_to_use = session if session is not None else self._session
283
390
  return await run_async(
284
391
  agent=self.get_agent(),
285
392
  input=input,
286
393
  context=context,
287
394
  output_type=output_type,
395
+ session=session_to_use,
288
396
  )
289
397
 
290
398
  def run_sync(
@@ -293,6 +401,7 @@ class AgentBase:
293
401
  *,
294
402
  context: Optional[Dict[str, Any]] = None,
295
403
  output_type: Optional[Any] = None,
404
+ session: Optional[Any] = None,
296
405
  ) -> Any:
297
406
  """Run the agent synchronously.
298
407
 
@@ -304,17 +413,23 @@ class AgentBase:
304
413
  Optional dictionary passed to the agent.
305
414
  output_type : type or None, default=None
306
415
  Optional type used to cast the final output.
416
+ session : Session or None, default=None
417
+ Optional session for maintaining conversation history across runs.
418
+ If not provided, uses the session from config if available.
307
419
 
308
420
  Returns
309
421
  -------
310
422
  Any
311
423
  Agent result, optionally converted to ``output_type``.
312
424
  """
425
+ # Use session from parameter, fall back to config session
426
+ session_to_use = session if session is not None else self._session
313
427
  return run_sync(
314
428
  agent=self.get_agent(),
315
429
  input=input,
316
430
  context=context,
317
431
  output_type=output_type,
432
+ session=session_to_use,
318
433
  )
319
434
 
320
435
  def run_streamed(
@@ -323,6 +438,7 @@ class AgentBase:
323
438
  *,
324
439
  context: Optional[Dict[str, Any]] = None,
325
440
  output_type: Optional[Any] = None,
441
+ session: Optional[Any] = None,
326
442
  ) -> RunResultStreaming:
327
443
  """Stream the agent execution results.
328
444
 
@@ -334,16 +450,22 @@ class AgentBase:
334
450
  Optional dictionary passed to the agent.
335
451
  output_type : type or None, default=None
336
452
  Optional type used to cast the final output.
453
+ session : Session or None, default=None
454
+ Optional session for maintaining conversation history across runs.
455
+ If not provided, uses the session from config if available.
337
456
 
338
457
  Returns
339
458
  -------
340
459
  RunResultStreaming
341
460
  Streaming output wrapper from the agent execution.
342
461
  """
462
+ # Use session from parameter, fall back to config session
463
+ session_to_use = session if session is not None else self._session
343
464
  result = run_streamed(
344
465
  agent=self.get_agent(),
345
466
  input=input,
346
467
  context=context,
468
+ session=session_to_use,
347
469
  )
348
470
  if self._output_type and not output_type:
349
471
  output_type = self._output_type
@@ -351,19 +473,61 @@ class AgentBase:
351
473
  return result.final_output_as(output_type)
352
474
  return result
353
475
 
354
- def as_tool(self) -> FunctionTool:
476
+ def as_tool(self) -> Tool:
355
477
  """Return the agent as a callable tool.
356
478
 
357
479
  Returns
358
480
  -------
359
- FunctionTool
481
+ Tool
360
482
  Tool instance wrapping this agent.
361
483
  """
362
484
  agent = self.get_agent()
363
- tool_obj: FunctionTool = agent.as_tool(
485
+ tool_obj: Tool = agent.as_tool(
364
486
  tool_name=self.agent_name, tool_description=self.description
365
- ) # type: ignore
487
+ )
366
488
  return tool_obj
367
489
 
490
+ def __enter__(self) -> BaseAgent:
491
+ """Enter the context manager for resource management.
492
+
493
+ Returns
494
+ -------
495
+ BaseAgent
496
+ Self reference for use in with statements.
497
+ """
498
+ return self
499
+
500
+ def __exit__(self, exc_type, exc_val, exc_tb) -> None:
501
+ """Exit the context manager and clean up resources.
502
+
503
+ Parameters
504
+ ----------
505
+ exc_type : type or None
506
+ Exception type if an exception occurred, otherwise None.
507
+ exc_val : Exception or None
508
+ Exception instance if an exception occurred, otherwise None.
509
+ exc_tb : traceback or None
510
+ Traceback object if an exception occurred, otherwise None.
511
+ """
512
+ self.close()
513
+
514
+ def close(self) -> None:
515
+ """Clean up agent resources.
516
+
517
+ This method is called automatically when using the agent as a
518
+ context manager. Override in subclasses to implement custom
519
+ cleanup logic.
520
+
521
+ Examples
522
+ --------
523
+ >>> agent = BaseAgent(config, default_model="gpt-4o-mini")
524
+ >>> try:
525
+ ... result = agent.run_sync("query")
526
+ ... finally:
527
+ ... agent.close()
528
+ """
529
+ # Base implementation does nothing, but subclasses can override
530
+ pass
531
+
368
532
 
369
- __all__ = ["AgentConfigLike", "AgentBase"]
533
+ __all__ = ["AgentConfigurationLike", "BaseAgent"]