openai-sdk-helpers 0.4.1__py3-none-any.whl → 0.4.3__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.
- openai_sdk_helpers/__init__.py +10 -36
- openai_sdk_helpers/agent/__init__.py +5 -6
- openai_sdk_helpers/agent/base.py +184 -39
- openai_sdk_helpers/agent/{config.py → configuration.py} +50 -75
- openai_sdk_helpers/agent/{coordination.py → coordinator.py} +12 -10
- openai_sdk_helpers/agent/search/__init__.py +4 -4
- openai_sdk_helpers/agent/search/base.py +16 -16
- openai_sdk_helpers/agent/search/vector.py +66 -42
- openai_sdk_helpers/agent/search/web.py +33 -29
- openai_sdk_helpers/agent/summarizer.py +6 -4
- openai_sdk_helpers/agent/translator.py +9 -5
- openai_sdk_helpers/agent/{validation.py → validator.py} +6 -4
- openai_sdk_helpers/cli.py +8 -22
- openai_sdk_helpers/environment.py +17 -0
- openai_sdk_helpers/prompt/vector_planner.jinja +7 -0
- openai_sdk_helpers/prompt/vector_search.jinja +6 -0
- openai_sdk_helpers/prompt/vector_writer.jinja +7 -0
- openai_sdk_helpers/response/__init__.py +1 -1
- openai_sdk_helpers/response/base.py +4 -4
- openai_sdk_helpers/response/{config.py → configuration.py} +9 -9
- openai_sdk_helpers/response/planner.py +12 -0
- openai_sdk_helpers/response/prompter.py +12 -0
- openai_sdk_helpers/streamlit_app/__init__.py +1 -1
- openai_sdk_helpers/streamlit_app/app.py +16 -17
- openai_sdk_helpers/streamlit_app/{config.py → configuration.py} +13 -13
- openai_sdk_helpers/streamlit_app/streamlit_web_search.py +3 -3
- openai_sdk_helpers/types.py +3 -3
- openai_sdk_helpers/utils/__init__.py +2 -6
- openai_sdk_helpers/utils/json/base_model.py +1 -1
- openai_sdk_helpers/utils/json/data_class.py +1 -1
- openai_sdk_helpers/utils/json/ref.py +3 -0
- openai_sdk_helpers/utils/registry.py +19 -15
- openai_sdk_helpers/vector_storage/storage.py +1 -1
- {openai_sdk_helpers-0.4.1.dist-info → openai_sdk_helpers-0.4.3.dist-info}/METADATA +8 -8
- {openai_sdk_helpers-0.4.1.dist-info → openai_sdk_helpers-0.4.3.dist-info}/RECORD +40 -40
- openai_sdk_helpers/agent/prompt_utils.py +0 -15
- openai_sdk_helpers/context_manager.py +0 -241
- openai_sdk_helpers/deprecation.py +0 -167
- openai_sdk_helpers/retry.py +0 -175
- openai_sdk_helpers/utils/deprecation.py +0 -167
- /openai_sdk_helpers/{logging_config.py → logging.py} +0 -0
- /openai_sdk_helpers/{config.py → settings.py} +0 -0
- {openai_sdk_helpers-0.4.1.dist-info → openai_sdk_helpers-0.4.3.dist-info}/WHEEL +0 -0
- {openai_sdk_helpers-0.4.1.dist-info → openai_sdk_helpers-0.4.3.dist-info}/entry_points.txt +0 -0
- {openai_sdk_helpers-0.4.1.dist-info → openai_sdk_helpers-0.4.3.dist-info}/licenses/LICENSE +0 -0
|
@@ -24,12 +24,12 @@ class AgentRegistry(RegistryBase["AgentConfiguration"]):
|
|
|
24
24
|
Examples
|
|
25
25
|
--------
|
|
26
26
|
>>> registry = AgentRegistry()
|
|
27
|
-
>>>
|
|
27
|
+
>>> configuration = AgentConfiguration(
|
|
28
28
|
... name="test_agent",
|
|
29
29
|
... model="gpt-4o-mini",
|
|
30
30
|
... instructions="Test instructions"
|
|
31
31
|
... )
|
|
32
|
-
>>> registry.register(
|
|
32
|
+
>>> registry.register(configuration)
|
|
33
33
|
>>> retrieved = registry.get("test_agent")
|
|
34
34
|
>>> retrieved.name
|
|
35
35
|
'test_agent'
|
|
@@ -85,10 +85,10 @@ def get_default_registry() -> AgentRegistry:
|
|
|
85
85
|
Examples
|
|
86
86
|
--------
|
|
87
87
|
>>> registry = get_default_registry()
|
|
88
|
-
>>>
|
|
88
|
+
>>> configuration = AgentConfiguration(
|
|
89
89
|
... name="test", model="gpt-4o-mini", instructions="Test instructions"
|
|
90
90
|
... )
|
|
91
|
-
>>> registry.register(
|
|
91
|
+
>>> registry.register(configuration)
|
|
92
92
|
"""
|
|
93
93
|
return _default_registry
|
|
94
94
|
|
|
@@ -165,12 +165,12 @@ class AgentConfiguration(DataclassJSONSerializable):
|
|
|
165
165
|
|
|
166
166
|
Examples
|
|
167
167
|
--------
|
|
168
|
-
>>>
|
|
168
|
+
>>> configuration = AgentConfiguration(
|
|
169
169
|
... name="summarizer",
|
|
170
170
|
... description="Summarizes text",
|
|
171
171
|
... model="gpt-4o-mini"
|
|
172
172
|
... )
|
|
173
|
-
>>>
|
|
173
|
+
>>> configuration.name
|
|
174
174
|
'summarizer'
|
|
175
175
|
"""
|
|
176
176
|
|
|
@@ -187,9 +187,8 @@ class AgentConfiguration(DataclassJSONSerializable):
|
|
|
187
187
|
input_guardrails: Optional[list[InputGuardrail]] = None
|
|
188
188
|
output_guardrails: Optional[list[OutputGuardrail]] = None
|
|
189
189
|
session: Optional[Session] = None
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
)
|
|
190
|
+
add_output_instructions: bool = False
|
|
191
|
+
add_web_search_tool: bool = False
|
|
193
192
|
|
|
194
193
|
def __post_init__(self) -> None:
|
|
195
194
|
"""Validate configuration invariants after initialization.
|
|
@@ -258,11 +257,16 @@ class AgentConfiguration(DataclassJSONSerializable):
|
|
|
258
257
|
str
|
|
259
258
|
Plain-text instructions, loading template files when necessary.
|
|
260
259
|
"""
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
260
|
+
resolved_instructions: str = resolve_instructions_from_path(self.instructions)
|
|
261
|
+
output_instructions = ""
|
|
262
|
+
if self.output_structure is not None and self.add_output_instructions:
|
|
263
|
+
output_instructions = self.output_structure.get_prompt(
|
|
264
|
+
add_enum_values=False
|
|
265
|
+
)
|
|
266
|
+
if output_instructions:
|
|
267
|
+
return f"{resolved_instructions}\n{output_instructions}"
|
|
268
|
+
|
|
269
|
+
return resolved_instructions
|
|
266
270
|
|
|
267
271
|
def _resolve_instructions(self) -> str:
|
|
268
272
|
"""Resolve instructions from string or file path."""
|
|
@@ -304,7 +308,7 @@ class AgentConfiguration(DataclassJSONSerializable):
|
|
|
304
308
|
prompt_dir : Path or None, default=None
|
|
305
309
|
Optional directory holding prompt templates.
|
|
306
310
|
default_model : str or None, default=None
|
|
307
|
-
Optional fallback model identifier if
|
|
311
|
+
Optional fallback model identifier if configuration doesn't specify one.
|
|
308
312
|
|
|
309
313
|
Returns
|
|
310
314
|
-------
|
|
@@ -313,17 +317,17 @@ class AgentConfiguration(DataclassJSONSerializable):
|
|
|
313
317
|
|
|
314
318
|
Examples
|
|
315
319
|
--------
|
|
316
|
-
>>>
|
|
320
|
+
>>> configuration = AgentConfiguration(
|
|
317
321
|
... name="helper", model="gpt-4o-mini", instructions="Help the user"
|
|
318
322
|
... )
|
|
319
|
-
>>> agent =
|
|
323
|
+
>>> agent = configuration.gen_agent()
|
|
320
324
|
>>> result = agent.run_sync("Hello!")
|
|
321
325
|
"""
|
|
322
326
|
# Import here to avoid circular dependency
|
|
323
327
|
from .base import AgentBase
|
|
324
328
|
|
|
325
329
|
return AgentBase(
|
|
326
|
-
|
|
330
|
+
configuration=self,
|
|
327
331
|
run_context_wrapper=run_context_wrapper,
|
|
328
332
|
prompt_dir=prompt_dir,
|
|
329
333
|
default_model=default_model,
|
|
@@ -348,10 +352,10 @@ class AgentConfiguration(DataclassJSONSerializable):
|
|
|
348
352
|
|
|
349
353
|
Examples
|
|
350
354
|
--------
|
|
351
|
-
>>>
|
|
355
|
+
>>> configuration = AgentConfiguration(
|
|
352
356
|
... name="agent1", model="gpt-4o-mini", instructions="Agent instructions"
|
|
353
357
|
... )
|
|
354
|
-
>>> config2 =
|
|
358
|
+
>>> config2 = configuration.replace(name="agent2", description="Modified")
|
|
355
359
|
>>> config2.name
|
|
356
360
|
'agent2'
|
|
357
361
|
>>> config2.model
|
|
@@ -361,66 +365,37 @@ class AgentConfiguration(DataclassJSONSerializable):
|
|
|
361
365
|
|
|
362
366
|
return replace(self, **changes)
|
|
363
367
|
|
|
364
|
-
def
|
|
365
|
-
"""
|
|
366
|
-
|
|
367
|
-
Returns
|
|
368
|
-
-------
|
|
369
|
-
dict[str, Any]
|
|
370
|
-
Serialized configuration data without cached fields.
|
|
371
|
-
"""
|
|
372
|
-
data = DataclassJSONSerializable.to_json(self)
|
|
373
|
-
data.pop("_instructions_cache", None)
|
|
374
|
-
return data
|
|
375
|
-
|
|
376
|
-
@classmethod
|
|
377
|
-
def from_json(cls, data: dict[str, Any]) -> AgentConfiguration:
|
|
378
|
-
"""Create an AgentConfiguration from JSON data.
|
|
368
|
+
def to_response_config(self) -> Any:
|
|
369
|
+
"""Convert this AgentConfiguration to a ResponseConfiguration.
|
|
379
370
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
paths back to Path objects for proper file loading.
|
|
383
|
-
|
|
384
|
-
Parameters
|
|
385
|
-
----------
|
|
386
|
-
data : dict[str, Any]
|
|
387
|
-
Dictionary containing the configuration data.
|
|
371
|
+
This is a convenience method for creating a ResponseConfiguration
|
|
372
|
+
instance using the relevant fields from this agent configuration.
|
|
388
373
|
|
|
389
374
|
Returns
|
|
390
375
|
-------
|
|
391
|
-
|
|
392
|
-
New configuration instance.
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
376
|
+
ResponseConfiguration
|
|
377
|
+
New response configuration instance.
|
|
378
|
+
|
|
379
|
+
Examples
|
|
380
|
+
--------
|
|
381
|
+
>>> agent_config = AgentConfiguration(
|
|
382
|
+
... name="responder",
|
|
383
|
+
... model="gpt-4o-mini",
|
|
384
|
+
... instructions="Respond to user queries"
|
|
385
|
+
... )
|
|
386
|
+
>>> response_config = agent_config.to_response_config()
|
|
387
|
+
>>> response_config.name
|
|
388
|
+
'responder'
|
|
400
389
|
"""
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
# Check if it looks like a file path and the file exists
|
|
411
|
-
# This preserves the intended behavior for file-based instructions
|
|
412
|
-
try:
|
|
413
|
-
potential_path = Path(instructions_value)
|
|
414
|
-
# Only convert to Path if it's an existing file
|
|
415
|
-
# This way, plain text instructions stay as strings
|
|
416
|
-
if potential_path.exists() and potential_path.is_file():
|
|
417
|
-
data["instructions"] = potential_path
|
|
418
|
-
except (OSError, ValueError):
|
|
419
|
-
# If path parsing fails, keep it as a string (likely plain text)
|
|
420
|
-
pass
|
|
421
|
-
|
|
422
|
-
# Use the parent class method for the rest
|
|
423
|
-
return super(AgentConfiguration, cls).from_json(data)
|
|
390
|
+
from ..response.configuration import ResponseConfiguration
|
|
391
|
+
|
|
392
|
+
return ResponseConfiguration(
|
|
393
|
+
name=self.name,
|
|
394
|
+
instructions=self.instructions,
|
|
395
|
+
input_structure=self.input_structure,
|
|
396
|
+
output_structure=self.output_structure,
|
|
397
|
+
tools=self.tools,
|
|
398
|
+
)
|
|
424
399
|
|
|
425
400
|
|
|
426
401
|
# Global default registry instance
|
|
@@ -11,11 +11,11 @@ from pathlib import Path
|
|
|
11
11
|
from typing import Any, Callable, Dict, List, Optional
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
from ..structure import TaskStructure, PlanStructure, PromptStructure
|
|
15
|
-
from ..utils import
|
|
14
|
+
from ..structure import TaskStructure, PlanStructure, PromptStructure, AgentEnum
|
|
15
|
+
from ..utils import ensure_directory, log
|
|
16
16
|
from .base import AgentBase
|
|
17
|
-
from .
|
|
18
|
-
|
|
17
|
+
from .configuration import AgentConfiguration
|
|
18
|
+
|
|
19
19
|
|
|
20
20
|
PromptFn = Callable[[str], PromptStructure]
|
|
21
21
|
BuildPlanFn = Callable[[str], PlanStructure]
|
|
@@ -40,7 +40,7 @@ class CoordinatorAgent(AgentBase):
|
|
|
40
40
|
Base path for persisting project artifacts.
|
|
41
41
|
name : str
|
|
42
42
|
Name of the parent module for data organization.
|
|
43
|
-
|
|
43
|
+
configuration : AgentConfiguration or None, default=None
|
|
44
44
|
Optional agent configuration describing prompts and metadata.
|
|
45
45
|
prompt_dir : Path or None, default=None
|
|
46
46
|
Optional directory holding prompt templates.
|
|
@@ -84,7 +84,7 @@ class CoordinatorAgent(AgentBase):
|
|
|
84
84
|
summarize_fn: SummarizeFn,
|
|
85
85
|
module_data_path: Path,
|
|
86
86
|
name: str,
|
|
87
|
-
|
|
87
|
+
configuration: Optional[AgentConfiguration] = None,
|
|
88
88
|
prompt_dir: Optional[Path] = None,
|
|
89
89
|
default_model: Optional[str] = None,
|
|
90
90
|
) -> None:
|
|
@@ -104,7 +104,7 @@ class CoordinatorAgent(AgentBase):
|
|
|
104
104
|
Base path for persisting project artifacts.
|
|
105
105
|
name : str
|
|
106
106
|
Name of the parent module for data organization.
|
|
107
|
-
|
|
107
|
+
configuration : AgentConfiguration or None, default=None
|
|
108
108
|
Optional agent configuration describing prompts and metadata.
|
|
109
109
|
prompt_dir : Path or None, default=None
|
|
110
110
|
Optional directory holding prompt templates.
|
|
@@ -127,14 +127,16 @@ class CoordinatorAgent(AgentBase):
|
|
|
127
127
|
... name="test",
|
|
128
128
|
... )
|
|
129
129
|
"""
|
|
130
|
-
if
|
|
131
|
-
|
|
130
|
+
if configuration is None:
|
|
131
|
+
configuration = AgentConfiguration(
|
|
132
132
|
name="coordinator_agent",
|
|
133
133
|
instructions="Coordinate agents for planning and summarization.",
|
|
134
134
|
description="Coordinates agents for planning and summarization.",
|
|
135
135
|
)
|
|
136
136
|
super().__init__(
|
|
137
|
-
|
|
137
|
+
configuration=configuration,
|
|
138
|
+
prompt_dir=prompt_dir,
|
|
139
|
+
default_model=default_model,
|
|
138
140
|
)
|
|
139
141
|
self._prompt_fn = prompt_fn
|
|
140
142
|
self._build_plan_fn = build_plan_fn
|
|
@@ -10,10 +10,10 @@ from .web import (
|
|
|
10
10
|
)
|
|
11
11
|
from .vector import (
|
|
12
12
|
MAX_CONCURRENT_SEARCHES as VECTOR_MAX_CONCURRENT_SEARCHES,
|
|
13
|
-
|
|
13
|
+
VectorAgentPlanner,
|
|
14
14
|
VectorSearchTool,
|
|
15
15
|
VectorSearchWriter,
|
|
16
|
-
|
|
16
|
+
VectorAgentSearch,
|
|
17
17
|
)
|
|
18
18
|
|
|
19
19
|
__all__ = [
|
|
@@ -26,8 +26,8 @@ __all__ = [
|
|
|
26
26
|
"WebAgentWriter",
|
|
27
27
|
"WebAgentSearch",
|
|
28
28
|
"VECTOR_MAX_CONCURRENT_SEARCHES",
|
|
29
|
-
"
|
|
29
|
+
"VectorAgentPlanner",
|
|
30
30
|
"VectorSearchTool",
|
|
31
31
|
"VectorSearchWriter",
|
|
32
|
-
"
|
|
32
|
+
"VectorAgentSearch",
|
|
33
33
|
]
|
|
@@ -13,7 +13,7 @@ from pathlib import Path
|
|
|
13
13
|
from typing import Generic, List, Optional, TypeVar, Union
|
|
14
14
|
|
|
15
15
|
from ..base import AgentBase
|
|
16
|
-
from ..
|
|
16
|
+
from ..configuration import AgentConfiguration
|
|
17
17
|
from ...structure.base import StructureBase
|
|
18
18
|
|
|
19
19
|
# Type variables for search workflow components
|
|
@@ -36,7 +36,7 @@ class SearchPlanner(AgentBase, Generic[PlanType]):
|
|
|
36
36
|
prompt_dir : Path, optional
|
|
37
37
|
Directory containing prompt templates.
|
|
38
38
|
default_model : str, optional
|
|
39
|
-
Default model identifier to use when not defined in
|
|
39
|
+
Default model identifier to use when not defined in configuration.
|
|
40
40
|
|
|
41
41
|
Methods
|
|
42
42
|
-------
|
|
@@ -68,9 +68,9 @@ class SearchPlanner(AgentBase, Generic[PlanType]):
|
|
|
68
68
|
default_model: Optional[str] = None,
|
|
69
69
|
) -> None:
|
|
70
70
|
"""Initialize the planner agent."""
|
|
71
|
-
|
|
71
|
+
configuration = self._configure_agent()
|
|
72
72
|
super().__init__(
|
|
73
|
-
|
|
73
|
+
configuration=configuration,
|
|
74
74
|
prompt_dir=prompt_dir,
|
|
75
75
|
default_model=default_model,
|
|
76
76
|
)
|
|
@@ -86,12 +86,12 @@ class SearchPlanner(AgentBase, Generic[PlanType]):
|
|
|
86
86
|
|
|
87
87
|
Examples
|
|
88
88
|
--------
|
|
89
|
-
>>>
|
|
89
|
+
>>> configuration = AgentConfiguration(
|
|
90
90
|
... name="web_planner",
|
|
91
91
|
... description="Plan web searches",
|
|
92
92
|
... output_structure=WebSearchPlanStructure,
|
|
93
93
|
... )
|
|
94
|
-
>>> return
|
|
94
|
+
>>> return configuration
|
|
95
95
|
"""
|
|
96
96
|
pass
|
|
97
97
|
|
|
@@ -127,7 +127,7 @@ class SearchToolAgent(AgentBase, Generic[ItemType, ResultType, PlanType]):
|
|
|
127
127
|
prompt_dir : Path, optional
|
|
128
128
|
Directory containing prompt templates.
|
|
129
129
|
default_model : str, optional
|
|
130
|
-
Default model identifier to use when not defined in
|
|
130
|
+
Default model identifier to use when not defined in configuration.
|
|
131
131
|
max_concurrent_searches : int, default=10
|
|
132
132
|
Maximum number of concurrent search operations.
|
|
133
133
|
|
|
@@ -168,9 +168,9 @@ class SearchToolAgent(AgentBase, Generic[ItemType, ResultType, PlanType]):
|
|
|
168
168
|
) -> None:
|
|
169
169
|
"""Initialize the search tool agent."""
|
|
170
170
|
self._max_concurrent_searches = max_concurrent_searches
|
|
171
|
-
|
|
171
|
+
configuration = self._configure_agent()
|
|
172
172
|
super().__init__(
|
|
173
|
-
|
|
173
|
+
configuration=configuration,
|
|
174
174
|
prompt_dir=prompt_dir,
|
|
175
175
|
default_model=default_model,
|
|
176
176
|
)
|
|
@@ -186,13 +186,13 @@ class SearchToolAgent(AgentBase, Generic[ItemType, ResultType, PlanType]):
|
|
|
186
186
|
|
|
187
187
|
Examples
|
|
188
188
|
--------
|
|
189
|
-
>>>
|
|
189
|
+
>>> configuration = AgentConfiguration(
|
|
190
190
|
... name="web_search",
|
|
191
191
|
... description="Perform web searches",
|
|
192
192
|
... input_structure=WebSearchPlanStructure,
|
|
193
193
|
... tools=[WebSearchTool()],
|
|
194
194
|
... )
|
|
195
|
-
>>> return
|
|
195
|
+
>>> return configuration
|
|
196
196
|
"""
|
|
197
197
|
pass
|
|
198
198
|
|
|
@@ -250,7 +250,7 @@ class SearchWriter(AgentBase, Generic[ReportType]):
|
|
|
250
250
|
prompt_dir : Path, optional
|
|
251
251
|
Directory containing prompt templates.
|
|
252
252
|
default_model : str, optional
|
|
253
|
-
Default model identifier to use when not defined in
|
|
253
|
+
Default model identifier to use when not defined in configuration.
|
|
254
254
|
|
|
255
255
|
Methods
|
|
256
256
|
-------
|
|
@@ -282,9 +282,9 @@ class SearchWriter(AgentBase, Generic[ReportType]):
|
|
|
282
282
|
default_model: Optional[str] = None,
|
|
283
283
|
) -> None:
|
|
284
284
|
"""Initialize the writer agent."""
|
|
285
|
-
|
|
285
|
+
configuration = self._configure_agent()
|
|
286
286
|
super().__init__(
|
|
287
|
-
|
|
287
|
+
configuration=configuration,
|
|
288
288
|
prompt_dir=prompt_dir,
|
|
289
289
|
default_model=default_model,
|
|
290
290
|
)
|
|
@@ -300,12 +300,12 @@ class SearchWriter(AgentBase, Generic[ReportType]):
|
|
|
300
300
|
|
|
301
301
|
Examples
|
|
302
302
|
--------
|
|
303
|
-
>>>
|
|
303
|
+
>>> configuration = AgentConfiguration(
|
|
304
304
|
... name="web_writer",
|
|
305
305
|
... description="Write web search report",
|
|
306
306
|
... output_structure=WebSearchReportStructure,
|
|
307
307
|
... )
|
|
308
|
-
>>> return
|
|
308
|
+
>>> return configuration
|
|
309
309
|
"""
|
|
310
310
|
pass
|
|
311
311
|
|
|
@@ -6,7 +6,10 @@ from pathlib import Path
|
|
|
6
6
|
from typing import Any, Callable, Dict, List, Optional
|
|
7
7
|
|
|
8
8
|
from agents import custom_span, gen_trace_id, trace
|
|
9
|
+
from agents.model_settings import ModelSettings
|
|
9
10
|
|
|
11
|
+
from ...environment import DEFAULT_PROMPT_DIR
|
|
12
|
+
from ...structure.prompt import PromptStructure
|
|
10
13
|
from ...structure.vector_search import (
|
|
11
14
|
VectorSearchItemStructure,
|
|
12
15
|
VectorSearchItemResultStructure,
|
|
@@ -15,23 +18,25 @@ from ...structure.vector_search import (
|
|
|
15
18
|
VectorSearchPlanStructure,
|
|
16
19
|
VectorSearchReportStructure,
|
|
17
20
|
)
|
|
21
|
+
from ...tools import tool_handler_factory
|
|
18
22
|
from ...vector_storage import VectorStorage
|
|
19
|
-
from ..
|
|
23
|
+
from ..configuration import AgentConfiguration
|
|
20
24
|
from ..utils import run_coroutine_agent_sync
|
|
21
25
|
from .base import SearchPlanner, SearchToolAgent, SearchWriter
|
|
22
26
|
|
|
23
27
|
MAX_CONCURRENT_SEARCHES = 10
|
|
24
28
|
|
|
25
29
|
|
|
26
|
-
class
|
|
30
|
+
class VectorAgentPlanner(SearchPlanner[VectorSearchPlanStructure]):
|
|
27
31
|
"""Plan vector searches to satisfy a user query.
|
|
28
32
|
|
|
29
33
|
Parameters
|
|
30
34
|
----------
|
|
31
35
|
prompt_dir : Path or None, default=None
|
|
32
|
-
Directory containing prompt templates.
|
|
36
|
+
Directory containing prompt templates. Defaults to the packaged
|
|
37
|
+
``prompt`` directory when not provided.
|
|
33
38
|
default_model : str or None, default=None
|
|
34
|
-
Default model identifier to use when not defined in
|
|
39
|
+
Default model identifier to use when not defined in configuration.
|
|
35
40
|
|
|
36
41
|
Methods
|
|
37
42
|
-------
|
|
@@ -52,7 +57,8 @@ class VectorSearchPlanner(SearchPlanner[VectorSearchPlanStructure]):
|
|
|
52
57
|
self, prompt_dir: Optional[Path] = None, default_model: Optional[str] = None
|
|
53
58
|
) -> None:
|
|
54
59
|
"""Initialize the planner agent."""
|
|
55
|
-
|
|
60
|
+
prompt_directory = prompt_dir or DEFAULT_PROMPT_DIR
|
|
61
|
+
super().__init__(prompt_dir=prompt_directory, default_model=default_model)
|
|
56
62
|
|
|
57
63
|
def _configure_agent(self) -> AgentConfiguration:
|
|
58
64
|
"""Return configuration for the vector planner agent.
|
|
@@ -67,6 +73,7 @@ class VectorSearchPlanner(SearchPlanner[VectorSearchPlanStructure]):
|
|
|
67
73
|
instructions="Agent instructions",
|
|
68
74
|
description="Plan vector searches based on a user query.",
|
|
69
75
|
output_structure=VectorSearchPlanStructure,
|
|
76
|
+
model_settings=ModelSettings(tool_choice="none"),
|
|
70
77
|
)
|
|
71
78
|
|
|
72
79
|
|
|
@@ -82,9 +89,10 @@ class VectorSearchTool(
|
|
|
82
89
|
Parameters
|
|
83
90
|
----------
|
|
84
91
|
prompt_dir : Path or None, default=None
|
|
85
|
-
Directory containing prompt templates.
|
|
92
|
+
Directory containing prompt templates. Defaults to the packaged
|
|
93
|
+
``prompt`` directory when not provided.
|
|
86
94
|
default_model : str or None, default=None
|
|
87
|
-
Default model identifier to use when not defined in
|
|
95
|
+
Default model identifier to use when not defined in configuration.
|
|
88
96
|
store_name : str or None, default=None
|
|
89
97
|
Name of the vector store to query.
|
|
90
98
|
max_concurrent_searches : int, default=MAX_CONCURRENT_SEARCHES
|
|
@@ -123,13 +131,14 @@ class VectorSearchTool(
|
|
|
123
131
|
vector_storage_factory: Optional[Callable[[str], VectorStorage]] = None,
|
|
124
132
|
) -> None:
|
|
125
133
|
"""Initialize the search tool agent."""
|
|
134
|
+
prompt_directory = prompt_dir or DEFAULT_PROMPT_DIR
|
|
126
135
|
self._vector_storage: Optional[VectorStorage] = None
|
|
127
136
|
self._store_name = store_name or "editorial"
|
|
128
137
|
self._vector_storage_factory = vector_storage_factory
|
|
129
138
|
if vector_storage is not None:
|
|
130
139
|
self._vector_storage = vector_storage
|
|
131
140
|
super().__init__(
|
|
132
|
-
prompt_dir=
|
|
141
|
+
prompt_dir=prompt_directory,
|
|
133
142
|
default_model=default_model,
|
|
134
143
|
max_concurrent_searches=max_concurrent_searches,
|
|
135
144
|
)
|
|
@@ -148,6 +157,7 @@ class VectorSearchTool(
|
|
|
148
157
|
description="Perform vector searches based on a search plan.",
|
|
149
158
|
input_structure=VectorSearchPlanStructure,
|
|
150
159
|
output_structure=VectorSearchItemResultsStructure,
|
|
160
|
+
model_settings=ModelSettings(tool_choice="none"),
|
|
151
161
|
)
|
|
152
162
|
|
|
153
163
|
def _get_vector_storage(self) -> VectorStorage:
|
|
@@ -200,9 +210,10 @@ class VectorSearchWriter(SearchWriter[VectorSearchReportStructure]):
|
|
|
200
210
|
Parameters
|
|
201
211
|
----------
|
|
202
212
|
prompt_dir : Path or None, default=None
|
|
203
|
-
Directory containing prompt templates.
|
|
213
|
+
Directory containing prompt templates. Defaults to the packaged
|
|
214
|
+
``prompt`` directory when not provided.
|
|
204
215
|
default_model : str or None, default=None
|
|
205
|
-
Default model identifier to use when not defined in
|
|
216
|
+
Default model identifier to use when not defined in configuration.
|
|
206
217
|
|
|
207
218
|
Methods
|
|
208
219
|
-------
|
|
@@ -223,7 +234,8 @@ class VectorSearchWriter(SearchWriter[VectorSearchReportStructure]):
|
|
|
223
234
|
self, prompt_dir: Optional[Path] = None, default_model: Optional[str] = None
|
|
224
235
|
) -> None:
|
|
225
236
|
"""Initialize the writer agent."""
|
|
226
|
-
|
|
237
|
+
prompt_directory = prompt_dir or DEFAULT_PROMPT_DIR
|
|
238
|
+
super().__init__(prompt_dir=prompt_directory, default_model=default_model)
|
|
227
239
|
|
|
228
240
|
def _configure_agent(self) -> AgentConfiguration:
|
|
229
241
|
"""Return configuration for the vector writer agent.
|
|
@@ -238,10 +250,11 @@ class VectorSearchWriter(SearchWriter[VectorSearchReportStructure]):
|
|
|
238
250
|
instructions="Agent instructions",
|
|
239
251
|
description="Write a report based on search results.",
|
|
240
252
|
output_structure=VectorSearchReportStructure,
|
|
253
|
+
model_settings=ModelSettings(tool_choice="none"),
|
|
241
254
|
)
|
|
242
255
|
|
|
243
256
|
|
|
244
|
-
class
|
|
257
|
+
class VectorAgentSearch:
|
|
245
258
|
"""Manage the complete vector search workflow.
|
|
246
259
|
|
|
247
260
|
This high-level agent orchestrates a multi-step research process that plans
|
|
@@ -252,9 +265,10 @@ class VectorSearch:
|
|
|
252
265
|
Parameters
|
|
253
266
|
----------
|
|
254
267
|
prompt_dir : Path or None, default=None
|
|
255
|
-
Directory containing prompt templates.
|
|
268
|
+
Directory containing prompt templates. Defaults to the packaged
|
|
269
|
+
``prompt`` directory when not provided.
|
|
256
270
|
default_model : str or None, default=None
|
|
257
|
-
Default model identifier to use when not defined in
|
|
271
|
+
Default model identifier to use when not defined in configuration.
|
|
258
272
|
vector_store_name : str or None, default=None
|
|
259
273
|
Name of the vector store to query.
|
|
260
274
|
max_concurrent_searches : int, default=MAX_CONCURRENT_SEARCHES
|
|
@@ -292,6 +306,8 @@ class VectorSearch:
|
|
|
292
306
|
Execute the research workflow asynchronously.
|
|
293
307
|
run_agent_sync(search_query)
|
|
294
308
|
Execute the research workflow synchronously.
|
|
309
|
+
as_response_tool(vector_store_name, tool_name, tool_description)
|
|
310
|
+
Build a Responses API tool definition and handler.
|
|
295
311
|
run_vector_agent(search_query)
|
|
296
312
|
Convenience asynchronous entry point for the workflow.
|
|
297
313
|
run_vector_agent_sync(search_query)
|
|
@@ -306,15 +322,15 @@ class VectorSearch:
|
|
|
306
322
|
def __init__(
|
|
307
323
|
self,
|
|
308
324
|
*,
|
|
325
|
+
vector_store_name: str,
|
|
309
326
|
prompt_dir: Optional[Path] = None,
|
|
310
327
|
default_model: Optional[str] = None,
|
|
311
|
-
vector_store_name: Optional[str] = None,
|
|
312
328
|
max_concurrent_searches: int = MAX_CONCURRENT_SEARCHES,
|
|
313
329
|
vector_storage: Optional[VectorStorage] = None,
|
|
314
330
|
vector_storage_factory: Optional[Callable[[str], VectorStorage]] = None,
|
|
315
331
|
) -> None:
|
|
316
332
|
"""Create the main VectorSearch agent."""
|
|
317
|
-
self._prompt_dir = prompt_dir
|
|
333
|
+
self._prompt_dir = prompt_dir or DEFAULT_PROMPT_DIR
|
|
318
334
|
self._default_model = default_model
|
|
319
335
|
self._vector_store_name = vector_store_name
|
|
320
336
|
self._max_concurrent_searches = max_concurrent_searches
|
|
@@ -336,7 +352,7 @@ class VectorSearch:
|
|
|
336
352
|
"""
|
|
337
353
|
trace_id = gen_trace_id()
|
|
338
354
|
with trace("VectorSearch trace", trace_id=trace_id):
|
|
339
|
-
planner =
|
|
355
|
+
planner = VectorAgentPlanner(
|
|
340
356
|
prompt_dir=self._prompt_dir, default_model=self._default_model
|
|
341
357
|
)
|
|
342
358
|
tool = VectorSearchTool(
|
|
@@ -383,45 +399,53 @@ class VectorSearch:
|
|
|
383
399
|
"""
|
|
384
400
|
return run_coroutine_agent_sync(self.run_agent(search_query))
|
|
385
401
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
402
|
+
def as_response_tool(
|
|
403
|
+
self,
|
|
404
|
+
*,
|
|
405
|
+
tool_name: str = "vector_search",
|
|
406
|
+
tool_description: str = "Run the vector search workflow.",
|
|
407
|
+
) -> tuple[dict[str, Callable[..., Any]], dict[str, Any]]:
|
|
408
|
+
"""Return a Responses API tool handler and definition.
|
|
389
409
|
|
|
390
410
|
Parameters
|
|
391
411
|
----------
|
|
392
|
-
|
|
393
|
-
|
|
412
|
+
vector_store_name : str
|
|
413
|
+
Name of the vector store to use for the response tool.
|
|
414
|
+
tool_name : str, default="vector_search"
|
|
415
|
+
Name to use for the response tool.
|
|
416
|
+
tool_description : str, default="Run the vector search workflow."
|
|
417
|
+
Description for the response tool.
|
|
394
418
|
|
|
395
419
|
Returns
|
|
396
420
|
-------
|
|
397
|
-
|
|
398
|
-
|
|
421
|
+
tuple[dict[str, Callable[..., Any]], dict[str, Any]]
|
|
422
|
+
Tool handler mapping and tool definition for Responses API usage.
|
|
399
423
|
"""
|
|
400
|
-
|
|
424
|
+
search = VectorAgentSearch(
|
|
425
|
+
prompt_dir=self._prompt_dir,
|
|
426
|
+
default_model=self._default_model,
|
|
427
|
+
vector_store_name=self._vector_store_name,
|
|
428
|
+
max_concurrent_searches=self._max_concurrent_searches,
|
|
429
|
+
vector_storage=self._vector_storage,
|
|
430
|
+
vector_storage_factory=self._vector_storage_factory,
|
|
431
|
+
)
|
|
401
432
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
"""Run :meth:`run_vector_agent` synchronously for ``search_query``.
|
|
433
|
+
def _run_search(prompt: str) -> VectorSearchStructure:
|
|
434
|
+
return run_coroutine_agent_sync(search.run_agent(search_query=prompt))
|
|
405
435
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
Returns
|
|
412
|
-
-------
|
|
413
|
-
VectorSearchStructure
|
|
414
|
-
Completed research output.
|
|
415
|
-
"""
|
|
416
|
-
return run_coroutine_agent_sync(
|
|
417
|
-
VectorSearch.run_vector_agent(search_query=search_query)
|
|
436
|
+
tool_handler = {
|
|
437
|
+
tool_name: tool_handler_factory(_run_search, input_model=PromptStructure)
|
|
438
|
+
}
|
|
439
|
+
tool_definition = PromptStructure.response_tool_definition(
|
|
440
|
+
tool_name, tool_description=tool_description
|
|
418
441
|
)
|
|
442
|
+
return tool_handler, tool_definition
|
|
419
443
|
|
|
420
444
|
|
|
421
445
|
__all__ = [
|
|
422
446
|
"MAX_CONCURRENT_SEARCHES",
|
|
423
|
-
"
|
|
447
|
+
"VectorAgentPlanner",
|
|
424
448
|
"VectorSearchTool",
|
|
425
449
|
"VectorSearchWriter",
|
|
426
|
-
"
|
|
450
|
+
"VectorAgentSearch",
|
|
427
451
|
]
|