openai-sdk-helpers 0.0.2__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 +34 -0
- openai_sdk_helpers/agent/__init__.py +23 -0
- openai_sdk_helpers/agent/base.py +432 -0
- openai_sdk_helpers/agent/config.py +66 -0
- openai_sdk_helpers/agent/project_manager.py +416 -0
- openai_sdk_helpers/agent/runner.py +117 -0
- openai_sdk_helpers/agent/utils.py +47 -0
- openai_sdk_helpers/agent/vector_search.py +418 -0
- openai_sdk_helpers/agent/web_search.py +404 -0
- openai_sdk_helpers/config.py +141 -0
- openai_sdk_helpers/enums/__init__.py +7 -0
- openai_sdk_helpers/enums/base.py +17 -0
- openai_sdk_helpers/environment.py +27 -0
- openai_sdk_helpers/prompt/__init__.py +77 -0
- openai_sdk_helpers/response/__init__.py +16 -0
- openai_sdk_helpers/response/base.py +477 -0
- openai_sdk_helpers/response/messages.py +211 -0
- openai_sdk_helpers/response/runner.py +42 -0
- openai_sdk_helpers/response/tool_call.py +70 -0
- openai_sdk_helpers/structure/__init__.py +57 -0
- openai_sdk_helpers/structure/base.py +591 -0
- openai_sdk_helpers/structure/plan/__init__.py +13 -0
- openai_sdk_helpers/structure/plan/enum.py +48 -0
- openai_sdk_helpers/structure/plan/plan.py +104 -0
- openai_sdk_helpers/structure/plan/task.py +122 -0
- openai_sdk_helpers/structure/prompt.py +24 -0
- openai_sdk_helpers/structure/responses.py +148 -0
- openai_sdk_helpers/structure/summary.py +65 -0
- openai_sdk_helpers/structure/vector_search.py +82 -0
- openai_sdk_helpers/structure/web_search.py +46 -0
- openai_sdk_helpers/utils/__init__.py +13 -0
- openai_sdk_helpers/utils/core.py +208 -0
- openai_sdk_helpers/vector_storage/__init__.py +15 -0
- openai_sdk_helpers/vector_storage/cleanup.py +91 -0
- openai_sdk_helpers/vector_storage/storage.py +501 -0
- openai_sdk_helpers/vector_storage/types.py +58 -0
- openai_sdk_helpers-0.0.2.dist-info/METADATA +137 -0
- openai_sdk_helpers-0.0.2.dist-info/RECORD +40 -0
- openai_sdk_helpers-0.0.2.dist-info/WHEEL +4 -0
- openai_sdk_helpers-0.0.2.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
"""Core workflow management for ``vector search``."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Any, Dict, List, Optional
|
|
8
|
+
|
|
9
|
+
from agents import custom_span, gen_trace_id, trace
|
|
10
|
+
|
|
11
|
+
from ..structure.vector_search import (
|
|
12
|
+
VectorSearchItemStructure,
|
|
13
|
+
VectorSearchItemResultStructure,
|
|
14
|
+
VectorSearchItemResultsStructure,
|
|
15
|
+
VectorSearchStructure,
|
|
16
|
+
VectorSearchPlanStructure,
|
|
17
|
+
VectorSearchReportStructure,
|
|
18
|
+
)
|
|
19
|
+
from ..vector_storage import VectorStorage
|
|
20
|
+
from .base import BaseAgent, _run_agent
|
|
21
|
+
from .config import AgentConfig
|
|
22
|
+
from .utils import run_coro_sync
|
|
23
|
+
|
|
24
|
+
MAX_CONCURRENT_SEARCHES = 10
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class VectorSearchPlanner(BaseAgent):
|
|
28
|
+
"""Plan vector searches to satisfy a user query.
|
|
29
|
+
|
|
30
|
+
Methods
|
|
31
|
+
-------
|
|
32
|
+
run_agent(query)
|
|
33
|
+
Generate a vector search plan for the provided query.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
def __init__(
|
|
37
|
+
self, prompt_dir: Optional[Path] = None, default_model: Optional[str] = None
|
|
38
|
+
) -> None:
|
|
39
|
+
"""Initialize the planner agent.
|
|
40
|
+
|
|
41
|
+
Parameters
|
|
42
|
+
----------
|
|
43
|
+
prompt_dir : pathlib.Path or None, default=None
|
|
44
|
+
Directory containing prompt templates.
|
|
45
|
+
default_model : str or None, default=None
|
|
46
|
+
Default model identifier to use when not defined in config.
|
|
47
|
+
|
|
48
|
+
Returns
|
|
49
|
+
-------
|
|
50
|
+
None
|
|
51
|
+
"""
|
|
52
|
+
config = AgentConfig(
|
|
53
|
+
name="vector_planner",
|
|
54
|
+
description="Plan vector searches based on a user query.",
|
|
55
|
+
output_type=VectorSearchPlanStructure,
|
|
56
|
+
)
|
|
57
|
+
super().__init__(
|
|
58
|
+
config=config, prompt_dir=prompt_dir, default_model=default_model
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
async def run_agent(self, query: str) -> VectorSearchPlanStructure:
|
|
62
|
+
"""Create a search plan for ``query``.
|
|
63
|
+
|
|
64
|
+
Parameters
|
|
65
|
+
----------
|
|
66
|
+
query : str
|
|
67
|
+
User search query.
|
|
68
|
+
|
|
69
|
+
Returns
|
|
70
|
+
-------
|
|
71
|
+
VectorSearchPlanStructure
|
|
72
|
+
Generated search plan.
|
|
73
|
+
"""
|
|
74
|
+
result: VectorSearchPlanStructure = await _run_agent(
|
|
75
|
+
agent=self.get_agent(),
|
|
76
|
+
agent_input=query,
|
|
77
|
+
output_type=self._output_type,
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
return result
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class VectorSearchTool(BaseAgent):
|
|
84
|
+
"""Execute vector searches defined in a search plan.
|
|
85
|
+
|
|
86
|
+
Methods
|
|
87
|
+
-------
|
|
88
|
+
run_agent(search_plan)
|
|
89
|
+
Execute searches described by the plan.
|
|
90
|
+
run_search(item)
|
|
91
|
+
Perform a single vector search and summarise the result.
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
def __init__(
|
|
95
|
+
self,
|
|
96
|
+
prompt_dir: Optional[Path] = None,
|
|
97
|
+
default_model: Optional[str] = None,
|
|
98
|
+
store_name: Optional[str] = None,
|
|
99
|
+
) -> None:
|
|
100
|
+
"""Initialize the search tool agent.
|
|
101
|
+
|
|
102
|
+
Parameters
|
|
103
|
+
----------
|
|
104
|
+
prompt_dir : pathlib.Path or None, default=None
|
|
105
|
+
Directory containing prompt templates.
|
|
106
|
+
default_model : str or None, default=None
|
|
107
|
+
Default model identifier to use when not defined in config.
|
|
108
|
+
|
|
109
|
+
Returns
|
|
110
|
+
-------
|
|
111
|
+
None
|
|
112
|
+
"""
|
|
113
|
+
self._vector_storage: Optional[VectorStorage] = None
|
|
114
|
+
self._store_name = store_name or "editorial"
|
|
115
|
+
config = AgentConfig(
|
|
116
|
+
name="vector_search",
|
|
117
|
+
description="Perform vector searches based on a search plan.",
|
|
118
|
+
input_type=VectorSearchPlanStructure,
|
|
119
|
+
output_type=VectorSearchItemResultsStructure,
|
|
120
|
+
)
|
|
121
|
+
super().__init__(
|
|
122
|
+
config=config, prompt_dir=prompt_dir, default_model=default_model
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
def _get_vector_storage(self) -> VectorStorage:
|
|
126
|
+
"""Return a cached vector storage instance.
|
|
127
|
+
|
|
128
|
+
Returns
|
|
129
|
+
-------
|
|
130
|
+
VectorStorage
|
|
131
|
+
Vector storage helper for executing searches.
|
|
132
|
+
"""
|
|
133
|
+
if self._vector_storage is None:
|
|
134
|
+
self._vector_storage = VectorStorage(store_name=self._store_name)
|
|
135
|
+
return self._vector_storage
|
|
136
|
+
|
|
137
|
+
async def run_agent(
|
|
138
|
+
self, search_plan: VectorSearchPlanStructure
|
|
139
|
+
) -> VectorSearchItemResultsStructure:
|
|
140
|
+
"""Execute all searches in the plan with a progress bar.
|
|
141
|
+
|
|
142
|
+
Parameters
|
|
143
|
+
----------
|
|
144
|
+
search_plan : VectorSearchPlanStructure
|
|
145
|
+
Plan describing each search to perform.
|
|
146
|
+
|
|
147
|
+
Returns
|
|
148
|
+
-------
|
|
149
|
+
VectorSearchItemResultsStructure
|
|
150
|
+
Collection of results for the completed searches.
|
|
151
|
+
"""
|
|
152
|
+
with custom_span("Search vector store"):
|
|
153
|
+
semaphore = asyncio.Semaphore(MAX_CONCURRENT_SEARCHES)
|
|
154
|
+
|
|
155
|
+
async def _bounded_search(
|
|
156
|
+
item: VectorSearchItemStructure,
|
|
157
|
+
) -> VectorSearchItemResultStructure:
|
|
158
|
+
"""Execute a single search within the concurrency limit.
|
|
159
|
+
|
|
160
|
+
Parameters
|
|
161
|
+
----------
|
|
162
|
+
item : VectorSearchItemStructure
|
|
163
|
+
Search item to process.
|
|
164
|
+
|
|
165
|
+
Returns
|
|
166
|
+
-------
|
|
167
|
+
VectorSearchItemResultStructure
|
|
168
|
+
Result of the search.
|
|
169
|
+
"""
|
|
170
|
+
async with semaphore:
|
|
171
|
+
return await self.run_search(item)
|
|
172
|
+
|
|
173
|
+
tasks = [
|
|
174
|
+
asyncio.create_task(_bounded_search(item))
|
|
175
|
+
for item in search_plan.searches
|
|
176
|
+
]
|
|
177
|
+
results_list = await asyncio.gather(*tasks)
|
|
178
|
+
results = VectorSearchItemResultsStructure()
|
|
179
|
+
for result in results_list:
|
|
180
|
+
if result is not None:
|
|
181
|
+
results.append(result)
|
|
182
|
+
return results
|
|
183
|
+
|
|
184
|
+
async def run_search(
|
|
185
|
+
self, item: VectorSearchItemStructure
|
|
186
|
+
) -> VectorSearchItemResultStructure:
|
|
187
|
+
"""Perform a single vector search using the search tool.
|
|
188
|
+
|
|
189
|
+
Parameters
|
|
190
|
+
----------
|
|
191
|
+
item : VectorSearchItemStructure
|
|
192
|
+
Search item containing the query and reason.
|
|
193
|
+
|
|
194
|
+
Returns
|
|
195
|
+
-------
|
|
196
|
+
VectorSearchItemResultStructure
|
|
197
|
+
Summarized search result. The ``texts`` attribute is empty when no
|
|
198
|
+
results are found.
|
|
199
|
+
"""
|
|
200
|
+
results = self._get_vector_storage().search(item.query)
|
|
201
|
+
if results is None:
|
|
202
|
+
texts: List[str] = []
|
|
203
|
+
else:
|
|
204
|
+
texts = [
|
|
205
|
+
content.text
|
|
206
|
+
for result in results.data
|
|
207
|
+
for content in (result.content or [])
|
|
208
|
+
if getattr(content, "text", None)
|
|
209
|
+
]
|
|
210
|
+
return VectorSearchItemResultStructure(texts=texts)
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
class VectorSearchWriter(BaseAgent):
|
|
214
|
+
"""Generate reports summarizing vector search results.
|
|
215
|
+
|
|
216
|
+
Methods
|
|
217
|
+
-------
|
|
218
|
+
run_agent(query, search_results)
|
|
219
|
+
Compile a final report from search results.
|
|
220
|
+
"""
|
|
221
|
+
|
|
222
|
+
def __init__(
|
|
223
|
+
self, prompt_dir: Optional[Path] = None, default_model: Optional[str] = None
|
|
224
|
+
) -> None:
|
|
225
|
+
"""Initialize the writer agent.
|
|
226
|
+
|
|
227
|
+
Parameters
|
|
228
|
+
----------
|
|
229
|
+
prompt_dir : pathlib.Path or None, default=None
|
|
230
|
+
Directory containing prompt templates.
|
|
231
|
+
default_model : str or None, default=None
|
|
232
|
+
Default model identifier to use when not defined in config.
|
|
233
|
+
|
|
234
|
+
Returns
|
|
235
|
+
-------
|
|
236
|
+
None
|
|
237
|
+
"""
|
|
238
|
+
config = AgentConfig(
|
|
239
|
+
name="vector_writer",
|
|
240
|
+
description="Write a report based on search results.",
|
|
241
|
+
output_type=VectorSearchReportStructure,
|
|
242
|
+
)
|
|
243
|
+
super().__init__(
|
|
244
|
+
config=config, prompt_dir=prompt_dir, default_model=default_model
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
async def run_agent(
|
|
248
|
+
self, query: str, search_results: VectorSearchItemResultsStructure
|
|
249
|
+
) -> VectorSearchReportStructure:
|
|
250
|
+
"""Compile a final report from search results.
|
|
251
|
+
|
|
252
|
+
Parameters
|
|
253
|
+
----------
|
|
254
|
+
query : str
|
|
255
|
+
Original search query.
|
|
256
|
+
search_results : VectorSearchItemResultsStructure
|
|
257
|
+
Results returned from the search step.
|
|
258
|
+
|
|
259
|
+
Returns
|
|
260
|
+
-------
|
|
261
|
+
VectorSearchReportStructure
|
|
262
|
+
Generated report for the query.
|
|
263
|
+
"""
|
|
264
|
+
template_context: Dict[str, Any] = {
|
|
265
|
+
"original_query": query,
|
|
266
|
+
"search_results": search_results,
|
|
267
|
+
}
|
|
268
|
+
result: VectorSearchReportStructure = await _run_agent(
|
|
269
|
+
agent=self.get_agent(),
|
|
270
|
+
agent_input=query,
|
|
271
|
+
agent_context=template_context,
|
|
272
|
+
output_type=self._output_type,
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
return result
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
class VectorSearch(BaseAgent):
|
|
279
|
+
"""Manage the complete vector search workflow.
|
|
280
|
+
|
|
281
|
+
Methods
|
|
282
|
+
-------
|
|
283
|
+
run_agent(search_query)
|
|
284
|
+
Execute the research workflow asynchronously.
|
|
285
|
+
run_agent_sync(search_query)
|
|
286
|
+
Execute the research workflow synchronously.
|
|
287
|
+
run_vector_agent(search_query)
|
|
288
|
+
Convenience asynchronous entry point for the workflow.
|
|
289
|
+
run_vector_agent_sync(search_query)
|
|
290
|
+
Convenience synchronous entry point for the workflow.
|
|
291
|
+
"""
|
|
292
|
+
|
|
293
|
+
def __init__(
|
|
294
|
+
self,
|
|
295
|
+
config: Optional[AgentConfig] = None,
|
|
296
|
+
prompt_dir: Optional[Path] = None,
|
|
297
|
+
default_model: Optional[str] = None,
|
|
298
|
+
vector_store_name: Optional[str] = None,
|
|
299
|
+
) -> None:
|
|
300
|
+
"""Create the main VectorSearch agent.
|
|
301
|
+
|
|
302
|
+
Parameters
|
|
303
|
+
----------
|
|
304
|
+
config : AgentConfig or None, default=None
|
|
305
|
+
Optional configuration for the agent.
|
|
306
|
+
prompt_dir : pathlib.Path or None, default=None
|
|
307
|
+
Directory containing prompt templates.
|
|
308
|
+
default_model : str or None, default=None
|
|
309
|
+
Default model identifier to use when not defined in config.
|
|
310
|
+
|
|
311
|
+
Returns
|
|
312
|
+
-------
|
|
313
|
+
None
|
|
314
|
+
"""
|
|
315
|
+
if config is None:
|
|
316
|
+
config = AgentConfig(
|
|
317
|
+
name="vector_agent",
|
|
318
|
+
description="Coordinates the research process, including planning, searching, and report writing.",
|
|
319
|
+
output_type=VectorSearchStructure,
|
|
320
|
+
input_type=VectorSearchReportStructure,
|
|
321
|
+
)
|
|
322
|
+
super().__init__(
|
|
323
|
+
config=config, prompt_dir=prompt_dir, default_model=default_model
|
|
324
|
+
)
|
|
325
|
+
self._prompt_dir = prompt_dir
|
|
326
|
+
self._vector_store_name = vector_store_name
|
|
327
|
+
|
|
328
|
+
async def run_agent(self, search_query: str) -> VectorSearchStructure:
|
|
329
|
+
"""Execute the entire research workflow for ``search_query``.
|
|
330
|
+
|
|
331
|
+
Parameters
|
|
332
|
+
----------
|
|
333
|
+
search_query : str
|
|
334
|
+
User's research query.
|
|
335
|
+
|
|
336
|
+
Returns
|
|
337
|
+
-------
|
|
338
|
+
VectorSearchStructure
|
|
339
|
+
Completed research output.
|
|
340
|
+
"""
|
|
341
|
+
trace_id = gen_trace_id()
|
|
342
|
+
with trace("VectorSearch trace", trace_id=trace_id):
|
|
343
|
+
planner = VectorSearchPlanner(
|
|
344
|
+
prompt_dir=self._prompt_dir, default_model=self.model
|
|
345
|
+
)
|
|
346
|
+
tool = VectorSearchTool(
|
|
347
|
+
prompt_dir=self._prompt_dir,
|
|
348
|
+
default_model=self.model,
|
|
349
|
+
store_name=self._vector_store_name,
|
|
350
|
+
)
|
|
351
|
+
writer = VectorSearchWriter(
|
|
352
|
+
prompt_dir=self._prompt_dir, default_model=self.model
|
|
353
|
+
)
|
|
354
|
+
search_plan = await planner.run_agent(query=search_query)
|
|
355
|
+
search_results = await tool.run_agent(search_plan=search_plan)
|
|
356
|
+
search_report = await writer.run_agent(search_query, search_results)
|
|
357
|
+
return VectorSearchStructure(
|
|
358
|
+
query=search_query,
|
|
359
|
+
plan=search_plan,
|
|
360
|
+
results=search_results,
|
|
361
|
+
report=search_report,
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
def run_agent_sync(self, search_query: str) -> VectorSearchStructure:
|
|
365
|
+
"""Run :meth:`run_agent` synchronously for ``search_query``.
|
|
366
|
+
|
|
367
|
+
Parameters
|
|
368
|
+
----------
|
|
369
|
+
search_query : str
|
|
370
|
+
User's research query.
|
|
371
|
+
|
|
372
|
+
Returns
|
|
373
|
+
-------
|
|
374
|
+
VectorSearchStructure
|
|
375
|
+
Completed research output.
|
|
376
|
+
"""
|
|
377
|
+
return run_coro_sync(self.run_agent(search_query))
|
|
378
|
+
|
|
379
|
+
@staticmethod
|
|
380
|
+
async def run_vector_agent(search_query: str) -> VectorSearchStructure:
|
|
381
|
+
"""Return a research report for the given query using ``VectorSearch``.
|
|
382
|
+
|
|
383
|
+
Parameters
|
|
384
|
+
----------
|
|
385
|
+
search_query : str
|
|
386
|
+
User's research query.
|
|
387
|
+
|
|
388
|
+
Returns
|
|
389
|
+
-------
|
|
390
|
+
VectorSearchStructure
|
|
391
|
+
Completed research output.
|
|
392
|
+
"""
|
|
393
|
+
return await VectorSearch().run_agent(search_query=search_query)
|
|
394
|
+
|
|
395
|
+
@staticmethod
|
|
396
|
+
def run_vector_agent_sync(search_query: str) -> VectorSearchStructure:
|
|
397
|
+
"""Run :meth:`run_vector_agent` synchronously for ``search_query``.
|
|
398
|
+
|
|
399
|
+
Parameters
|
|
400
|
+
----------
|
|
401
|
+
search_query : str
|
|
402
|
+
User's research query.
|
|
403
|
+
|
|
404
|
+
Returns
|
|
405
|
+
-------
|
|
406
|
+
VectorSearchStructure
|
|
407
|
+
Completed research output.
|
|
408
|
+
"""
|
|
409
|
+
return run_coro_sync(VectorSearch.run_vector_agent(search_query=search_query))
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
__all__ = [
|
|
413
|
+
"MAX_CONCURRENT_SEARCHES",
|
|
414
|
+
"VectorSearchPlanner",
|
|
415
|
+
"VectorSearchTool",
|
|
416
|
+
"VectorSearchWriter",
|
|
417
|
+
"VectorSearch",
|
|
418
|
+
]
|