openai-sdk-helpers 0.0.2__py3-none-any.whl → 0.0.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.
Files changed (45) hide show
  1. openai_sdk_helpers/prompt/summarizer.jinja +7 -0
  2. openai_sdk_helpers/prompt/translator.jinja +7 -0
  3. openai_sdk_helpers/prompt/validator.jinja +7 -0
  4. openai_sdk_helpers/py.typed +0 -0
  5. {openai_sdk_helpers-0.0.2.dist-info → openai_sdk_helpers-0.0.3.dist-info}/METADATA +57 -4
  6. openai_sdk_helpers-0.0.3.dist-info/RECORD +8 -0
  7. openai_sdk_helpers/__init__.py +0 -34
  8. openai_sdk_helpers/agent/__init__.py +0 -23
  9. openai_sdk_helpers/agent/base.py +0 -432
  10. openai_sdk_helpers/agent/config.py +0 -66
  11. openai_sdk_helpers/agent/project_manager.py +0 -416
  12. openai_sdk_helpers/agent/runner.py +0 -117
  13. openai_sdk_helpers/agent/utils.py +0 -47
  14. openai_sdk_helpers/agent/vector_search.py +0 -418
  15. openai_sdk_helpers/agent/web_search.py +0 -404
  16. openai_sdk_helpers/config.py +0 -141
  17. openai_sdk_helpers/enums/__init__.py +0 -7
  18. openai_sdk_helpers/enums/base.py +0 -17
  19. openai_sdk_helpers/environment.py +0 -27
  20. openai_sdk_helpers/prompt/__init__.py +0 -77
  21. openai_sdk_helpers/response/__init__.py +0 -16
  22. openai_sdk_helpers/response/base.py +0 -477
  23. openai_sdk_helpers/response/messages.py +0 -211
  24. openai_sdk_helpers/response/runner.py +0 -42
  25. openai_sdk_helpers/response/tool_call.py +0 -70
  26. openai_sdk_helpers/structure/__init__.py +0 -57
  27. openai_sdk_helpers/structure/base.py +0 -591
  28. openai_sdk_helpers/structure/plan/__init__.py +0 -13
  29. openai_sdk_helpers/structure/plan/enum.py +0 -48
  30. openai_sdk_helpers/structure/plan/plan.py +0 -104
  31. openai_sdk_helpers/structure/plan/task.py +0 -122
  32. openai_sdk_helpers/structure/prompt.py +0 -24
  33. openai_sdk_helpers/structure/responses.py +0 -148
  34. openai_sdk_helpers/structure/summary.py +0 -65
  35. openai_sdk_helpers/structure/vector_search.py +0 -82
  36. openai_sdk_helpers/structure/web_search.py +0 -46
  37. openai_sdk_helpers/utils/__init__.py +0 -13
  38. openai_sdk_helpers/utils/core.py +0 -208
  39. openai_sdk_helpers/vector_storage/__init__.py +0 -15
  40. openai_sdk_helpers/vector_storage/cleanup.py +0 -91
  41. openai_sdk_helpers/vector_storage/storage.py +0 -501
  42. openai_sdk_helpers/vector_storage/types.py +0 -58
  43. openai_sdk_helpers-0.0.2.dist-info/RECORD +0 -40
  44. {openai_sdk_helpers-0.0.2.dist-info → openai_sdk_helpers-0.0.3.dist-info}/WHEEL +0 -0
  45. {openai_sdk_helpers-0.0.2.dist-info → openai_sdk_helpers-0.0.3.dist-info}/licenses/LICENSE +0 -0
@@ -1,501 +0,0 @@
1
- """Wrapper utilities for managing OpenAI vector stores."""
2
-
3
- from __future__ import annotations
4
-
5
- import glob
6
- import logging
7
- import mimetypes
8
- import os
9
- from concurrent.futures import ThreadPoolExecutor, as_completed
10
- from typing import List, Optional, Union
11
-
12
- from openai import OpenAI
13
- from openai.pagination import SyncPage
14
- from openai.types.vector_store import VectorStore
15
- from openai.types.vector_store_search_response import VectorStoreSearchResponse
16
- from tqdm import tqdm
17
-
18
- from ..utils import ensure_list, log
19
- from .types import VectorStorageFileInfo, VectorStorageFileStats
20
-
21
- TEXT_MIME_PREFIXES = ("text/",)
22
- ALLOWED_TEXT_MIME_TYPES = {
23
- "text/x-c",
24
- "text/x-c++",
25
- "text/x-csharp",
26
- "text/css",
27
- "text/x-golang",
28
- "text/html",
29
- "text/x-java",
30
- "text/javascript",
31
- "application/json",
32
- "text/markdown",
33
- "text/x-python",
34
- "text/x-script.python",
35
- "text/x-ruby",
36
- "application/x-sh",
37
- "text/x-tex",
38
- "application/typescript",
39
- "text/plain",
40
- }
41
-
42
-
43
- class VectorStorage:
44
- """Manage an OpenAI vector store.
45
-
46
- Methods
47
- -------
48
- id()
49
- Return the ID of the underlying vector store.
50
- existing_files()
51
- Map cached file names to their IDs.
52
- upload_file(file_path, purpose, attributes, overwrite, refresh_cache)
53
- Upload a single file to the vector store.
54
- upload_files(file_patterns, purpose, attributes, overwrite)
55
- Upload files matching glob patterns by using a thread pool.
56
- delete_file(file_id)
57
- Delete a specific file from the vector store.
58
- delete_files(file_ids)
59
- Delete multiple files from the vector store.
60
- delete()
61
- Delete the entire vector store and associated files.
62
- search(query, top_k)
63
- Perform a search within the vector store.
64
- summarize(query, top_k)
65
- Summarize top search results returned by the vector store.
66
- """
67
-
68
- def __init__(
69
- self,
70
- store_name: str,
71
- client: Optional[OpenAI] = None,
72
- model: Optional[str] = None,
73
- ) -> None:
74
- """Initialize the vector store helper.
75
-
76
- Parameters
77
- ----------
78
- store_name
79
- Name of the vector store to create or connect to.
80
- client
81
- Optional preconfigured ``OpenAI`` client. Default ``None``.
82
- model
83
- Embedding model identifier. Default ``None`` to read ``OPENAI_MODEL``.
84
-
85
- Raises
86
- ------
87
- ValueError
88
- If no API key or embedding model can be resolved.
89
- RuntimeError
90
- If the OpenAI client cannot be initialized.
91
- """
92
- if client is None:
93
- api_key = os.getenv("OPENAI_API_KEY")
94
- if api_key is None:
95
- raise ValueError("OpenAI API key is required")
96
- try:
97
- self._client = OpenAI(api_key=api_key)
98
- except Exception as exc:
99
- raise RuntimeError("Failed to initialize OpenAI client") from exc
100
- else:
101
- self._client = client
102
-
103
- self._model = model or os.getenv("OPENAI_MODEL")
104
- if self._model is None:
105
- raise ValueError("OpenAI model is required")
106
-
107
- self._vector_storage = self._get_or_create_vector_storage(store_name)
108
- self._existing_files: Optional[dict[str, str]] = {}
109
-
110
- @property
111
- def id(self) -> str:
112
- """Return the ID of the underlying OpenAI ``VectorStore`` object.
113
-
114
- Returns
115
- -------
116
- str
117
- Identifier of the vector store.
118
- """
119
- return self._vector_storage.id
120
-
121
- def _get_or_create_vector_storage(self, store_name: str) -> VectorStore:
122
- """Retrieve an existing vector store or create one if it does not exist.
123
-
124
- Parameters
125
- ----------
126
- store_name
127
- Desired name of the vector store.
128
-
129
- Returns
130
- -------
131
- VectorStore
132
- Retrieved or newly created vector store object.
133
- """
134
- vector_stores = self._client.vector_stores.list().data
135
- existing = next((vs for vs in vector_stores if vs.name == store_name), None)
136
- return existing or self._client.vector_stores.create(name=store_name)
137
-
138
- @property
139
- def existing_files(self) -> dict[str, str]:
140
- """Map file names to their IDs for files currently in the vector store.
141
-
142
- This property lazily loads the file list from the OpenAI API on first
143
- access and caches it. The cache can be refreshed by calling
144
- ``_load_existing_files`` or by setting ``refresh_cache=True`` in
145
- ``upload_file``.
146
-
147
- Returns
148
- -------
149
- dict[str, str]
150
- Mapping of file names to file IDs.
151
- """
152
- if self._existing_files is None:
153
- try:
154
- files = self._client.vector_stores.files.list(
155
- vector_store_id=self._vector_storage.id
156
- )
157
- self._existing_files = {}
158
- for f in files:
159
- file_name = (f.attributes or {}).get("file_name")
160
- if isinstance(file_name, str) and f.id:
161
- self._existing_files[file_name] = f.id
162
-
163
- except Exception as exc:
164
- log(f"Failed to load existing files: {exc}", level=logging.ERROR)
165
- self._existing_files = {}
166
- return self._existing_files
167
-
168
- def _load_existing_files(self) -> dict[str, str]:
169
- """Force a reload of the existing files from the OpenAI API.
170
-
171
- Returns
172
- -------
173
- dict[str, str]
174
- Updated mapping of file names to file IDs.
175
- """
176
- try:
177
- files = self._client.vector_stores.files.list(
178
- vector_store_id=self._vector_storage.id
179
- )
180
- result: dict[str, str] = {}
181
- for f in files:
182
- file_name = (f.attributes or {}).get("file_name")
183
- if isinstance(file_name, str) and f.id:
184
- result[file_name] = f.id
185
- return result
186
- except Exception as exc:
187
- log(f"Failed to load existing files: {exc}", level=logging.ERROR)
188
- return {}
189
-
190
- def upload_file(
191
- self,
192
- file_path: str,
193
- purpose: str = "assistants",
194
- attributes: Optional[dict[str, str | float | bool]] = None,
195
- overwrite: bool = False,
196
- refresh_cache: bool = False,
197
- ) -> VectorStorageFileInfo:
198
- """Upload a single file to the vector store.
199
-
200
- Parameters
201
- ----------
202
- file_path
203
- Local path to the file to upload.
204
- purpose
205
- Purpose of the file (for example ``"assistants"``). Default
206
- ``"assistants"``.
207
- attributes
208
- Custom attributes to associate with the file. The ``file_name``
209
- attribute is added automatically. Default ``None``.
210
- overwrite
211
- When ``True``, re-upload even if a file with the same name already
212
- exists. Default ``False``.
213
- refresh_cache
214
- When ``True``, refresh the local cache of existing files before
215
- checking for duplicates. Default ``False``.
216
-
217
- Returns
218
- -------
219
- VectorStorageFileInfo
220
- Information about the uploaded file, including its ID and status.
221
- """
222
- file_name = os.path.basename(file_path)
223
- attributes = dict(attributes or {})
224
- attributes["file_name"] = file_name
225
-
226
- if refresh_cache:
227
- self._existing_files = self._load_existing_files()
228
-
229
- if not overwrite and file_name in self.existing_files:
230
- return VectorStorageFileInfo(
231
- name=file_name, id=self.existing_files[file_name], status="existing"
232
- )
233
-
234
- try:
235
- mime_type, _ = mimetypes.guess_type(file_path)
236
- mime_type = mime_type or ""
237
-
238
- if mime_type in ALLOWED_TEXT_MIME_TYPES or mime_type.startswith(
239
- TEXT_MIME_PREFIXES
240
- ):
241
- try:
242
- with open(file_path, "r", encoding="utf-8") as handle:
243
- content = handle.read()
244
- file_data = content.encode("utf-8")
245
- except UnicodeDecodeError:
246
- with open(file_path, "r", encoding="utf-16") as handle:
247
- content = handle.read()
248
- file_data = content.encode("utf-16")
249
- else:
250
- with open(file_path, "rb") as handle:
251
- file_data = handle.read()
252
-
253
- file = self._client.files.create(
254
- file=(file_path, file_data), purpose=purpose # type: ignore
255
- )
256
-
257
- self._client.vector_stores.files.create(
258
- self._vector_storage.id,
259
- file_id=file.id,
260
- attributes=attributes,
261
- )
262
-
263
- self._client.vector_stores.files.poll(
264
- file.id, vector_store_id=self._vector_storage.id
265
- )
266
-
267
- self.existing_files[file_name] = file.id
268
-
269
- return VectorStorageFileInfo(name=file_name, id=file.id, status="success")
270
- except Exception as exc:
271
- log(f"Error uploading {file_name}: {str(exc)}", level=logging.ERROR)
272
- return VectorStorageFileInfo(
273
- name=file_name, id="", status="error", error=str(exc)
274
- )
275
-
276
- def upload_files(
277
- self,
278
- file_patterns: Union[str, List[str]],
279
- purpose: str = "assistants",
280
- attributes: Optional[dict[str, str | float | bool]] = None,
281
- overwrite: bool = False,
282
- ) -> VectorStorageFileStats:
283
- """Upload files matching glob patterns to the vector store using a thread pool.
284
-
285
- Parameters
286
- ----------
287
- file_patterns
288
- Glob pattern or list of patterns (for example
289
- ``'/path/to/files/**/*.txt'``).
290
- purpose
291
- Purpose assigned to uploaded files. Default ``"assistants"``.
292
- attributes
293
- Custom attributes to associate with each file. Default ``None``.
294
- overwrite
295
- When ``True``, re-upload files even if files with the same name
296
- already exist. Default ``False``.
297
-
298
- Returns
299
- -------
300
- VectorStorageFileStats
301
- Aggregated statistics describing the upload results.
302
- """
303
- file_patterns = ensure_list(file_patterns)
304
-
305
- all_paths = set()
306
- for pattern in file_patterns:
307
- all_paths.update(glob.glob(pattern, recursive=True))
308
- if not all_paths:
309
- log("No files to upload.", level=logging.INFO)
310
- return VectorStorageFileStats(total=0)
311
-
312
- if not overwrite:
313
- existing_files = self.existing_files
314
- all_paths = [
315
- f for f in all_paths if os.path.basename(f) not in existing_files
316
- ]
317
-
318
- if not all_paths:
319
- log("No new files to upload.", level=logging.INFO)
320
- return VectorStorageFileStats()
321
-
322
- stats = VectorStorageFileStats(total=len(all_paths))
323
-
324
- with ThreadPoolExecutor(max_workers=10) as executor:
325
- futures = {
326
- executor.submit(
327
- self.upload_file,
328
- path,
329
- purpose,
330
- attributes,
331
- overwrite,
332
- False,
333
- ): path
334
- for path in all_paths
335
- }
336
-
337
- for future in tqdm(as_completed(futures), total=len(futures)):
338
- result = future.result()
339
- if result.status in {"success", "existing"}:
340
- stats.success += 1
341
- if result.status == "success":
342
- self.existing_files[result.name] = result.id
343
- else:
344
- stats.fail += 1
345
- stats.errors.append(result)
346
-
347
- return stats
348
-
349
- def delete_file(self, file_id: str) -> VectorStorageFileInfo:
350
- """Delete a specific file from the vector store.
351
-
352
- Parameters
353
- ----------
354
- file_id
355
- Identifier of the file to delete.
356
-
357
- Returns
358
- -------
359
- VectorStorageFileInfo
360
- Information about the deletion operation with status
361
- ``"success"`` or ``"failed"``.
362
- """
363
- try:
364
- self._client.vector_stores.files.delete(
365
- vector_store_id=self._vector_storage.id, file_id=file_id
366
- )
367
-
368
- to_remove = [k for k, v in self.existing_files.items() if v == file_id]
369
- for key in to_remove:
370
- del self.existing_files[key]
371
-
372
- return VectorStorageFileInfo(
373
- name=to_remove[0] if to_remove else "", id=file_id, status="success"
374
- )
375
- except Exception as exc:
376
- log(f"Error deleting file {file_id}: {str(exc)}", level=logging.ERROR)
377
- return VectorStorageFileInfo(
378
- name="", id=file_id, status="failed", error=str(exc)
379
- )
380
-
381
- def delete_files(self, file_ids: List[str]) -> VectorStorageFileStats:
382
- """Delete multiple files from the vector store using a thread pool.
383
-
384
- Parameters
385
- ----------
386
- file_ids
387
- List of file IDs to delete.
388
-
389
- Returns
390
- -------
391
- VectorStorageFileStats
392
- Aggregated statistics describing the deletion results.
393
- """
394
- total_files = len(file_ids)
395
- log(f"{total_files} files to delete...")
396
- stats = VectorStorageFileStats(total=total_files)
397
- with ThreadPoolExecutor(max_workers=10) as executor:
398
- futures = {
399
- executor.submit(self.delete_file, file_id): file_id
400
- for file_id in file_ids
401
- }
402
-
403
- for future in tqdm(as_completed(futures), total=len(futures)):
404
- result = future.result()
405
- if result.status == "success":
406
- stats.success += 1
407
- else:
408
- stats.fail += 1
409
- stats.errors.append(result)
410
-
411
- return stats
412
-
413
- def delete(self) -> None:
414
- """Delete the entire vector store and all associated files.
415
-
416
- This operation is irreversible. It first attempts to delete each file
417
- individually from the store (and updates the local cache) before
418
- deleting the store itself.
419
-
420
- Returns
421
- -------
422
- None
423
- """
424
- try:
425
- existing_files = list(self.existing_files.items())
426
- for file_name, file_id in existing_files:
427
- log(f"Deleting file {file_id} ({file_name}) from vector store")
428
- self.delete_file(file_id)
429
-
430
- self._client.vector_stores.delete(self._vector_storage.id)
431
- self._existing_files = None # clear cache
432
- log(f"Vector store '{self._vector_storage.name}' deleted successfully.")
433
-
434
- except Exception as exc:
435
- log(
436
- f"Error deleting vector store '{self._vector_storage.name}': {str(exc)}",
437
- level=logging.ERROR,
438
- )
439
-
440
- def search(
441
- self, query: str, top_k: int = 5
442
- ) -> Optional[SyncPage[VectorStoreSearchResponse]]:
443
- """Perform a search within the vector store.
444
-
445
- Parameters
446
- ----------
447
- query
448
- Search query string.
449
- top_k
450
- Maximum number of results to return. Default ``5``.
451
-
452
- Returns
453
- -------
454
- Optional[SyncPage[VectorStoreSearchResponse]]
455
- Page of search results from the OpenAI API, or ``None`` if an
456
- error occurs.
457
- """
458
- try:
459
- response = self._client.vector_stores.search(
460
- vector_store_id=self._vector_storage.id,
461
- query=query,
462
- max_num_results=top_k,
463
- )
464
- return response
465
- except Exception as exc:
466
- log(f"Error searching vector store: {str(exc)}", level=logging.ERROR)
467
- return None
468
-
469
- def summarize(self, query: str, top_k: int = 15) -> Optional[str]:
470
- """Perform a semantic search and summarize results by topic.
471
-
472
- Parameters
473
- ----------
474
- query
475
- Search query string used for summarization.
476
- top_k
477
- Number of top search results to retrieve and summarize. Default ``15``.
478
-
479
- Returns
480
- -------
481
- Optional[str]
482
- Summary generated by the OpenAI model or ``None`` when no results
483
- are available or an error occurs.
484
-
485
- Raises
486
- ------
487
- RuntimeError
488
- If no summarizer is configured for this core helper.
489
- """
490
- response = self.search(query, top_k=top_k)
491
- if not response or not response.data:
492
- log("No search results to summarize.", level=logging.WARNING)
493
- return None
494
-
495
- raise RuntimeError(
496
- "Summarizer is application-specific; override this method in an "
497
- "application wrapper."
498
- )
499
-
500
-
501
- __all__ = ["VectorStorage"]
@@ -1,58 +0,0 @@
1
- """Type definitions for vector storage."""
2
-
3
- from __future__ import annotations
4
-
5
- from dataclasses import dataclass, field
6
- from typing import List, Optional
7
-
8
-
9
- @dataclass
10
- class VectorStorageFileInfo:
11
- """Information about a file stored in a vector store.
12
-
13
- Attributes
14
- ----------
15
- name : str
16
- File name associated with the vector store item.
17
- id : str
18
- Unique identifier of the file in the vector store.
19
- status : str
20
- Outcome of the operation (for example ``"success"`` or ``"error"``).
21
- error : str, optional
22
- Error message when the operation fails. Default ``None``.
23
-
24
- Methods
25
- -------
26
- None
27
- """
28
-
29
- name: str
30
- id: str
31
- status: str
32
- error: Optional[str] = None
33
-
34
-
35
- @dataclass
36
- class VectorStorageFileStats:
37
- """Aggregate statistics about batch file operations.
38
-
39
- Attributes
40
- ----------
41
- total : int
42
- Total number of files processed.
43
- success : int
44
- Number of files successfully handled.
45
- fail : int
46
- Number of files that failed to process.
47
- errors : list[VectorStorageFileInfo]
48
- Details for each failed file.
49
-
50
- Methods
51
- -------
52
- None
53
- """
54
-
55
- total: int = 0
56
- success: int = 0
57
- fail: int = 0
58
- errors: List[VectorStorageFileInfo] = field(default_factory=list)
@@ -1,40 +0,0 @@
1
- openai_sdk_helpers/__init__.py,sha256=P4hUQXU7bfrltlPLQPw4iEv6tGw3qaVX6xSMuQs0BO0,779
2
- openai_sdk_helpers/config.py,sha256=O3MF2qypWWV9-zfmW3IXBWtud7YRojQDUhJVg9X49BE,4440
3
- openai_sdk_helpers/environment.py,sha256=t_AFP6OXjRBoIQVZdgjqZzcUWB-FDeYn4KzKn5FgrnY,693
4
- openai_sdk_helpers/agent/__init__.py,sha256=Nje9voDPuiYZfMekfCKUpuwKOXfH_zIkLHLsQVZ_juo,543
5
- openai_sdk_helpers/agent/base.py,sha256=aJ7ZN0IBcPP7_-Me-4GKz9VSx5ytpYQPpyTBBydFbFA,12729
6
- openai_sdk_helpers/agent/config.py,sha256=N7tzmwc5s6mpiTgF7b7tTsJCPOUycUwDNy1TcsQrZw0,1925
7
- openai_sdk_helpers/agent/project_manager.py,sha256=rKkIu-wG5GMbOoVg5zls6gf4DwSBdAKEyp_XL1i44iw,13529
8
- openai_sdk_helpers/agent/runner.py,sha256=cfgjgLZQYINK2WRMP7f-J22zz961i_woFZG2Zn-dW1g,3081
9
- openai_sdk_helpers/agent/utils.py,sha256=G7LR7koisYmpw0it-uEIEhxbif_GaFRUb6bALvIGNJY,1067
10
- openai_sdk_helpers/agent/vector_search.py,sha256=qV8Of37aBc7K8VvC0mJRegKMiner7OUq7SH6jtwM4Ms,12876
11
- openai_sdk_helpers/agent/web_search.py,sha256=ksjGH5VTr65WQPMaB-4RghleHtLey1xBv6YjG_jGpqM,12192
12
- openai_sdk_helpers/enums/__init__.py,sha256=HhzM9YVDqPijpnKzA-qnzbX62104FrGDcnN-cEYMD_w,149
13
- openai_sdk_helpers/enums/base.py,sha256=NGpnCYxS-6gsk-03zksu2m4tM8pGPQeAgM6YRcm159s,423
14
- openai_sdk_helpers/prompt/__init__.py,sha256=Pio9s99ej0ior5gKr8m-hSUgqkBOgFdNu1xofvjPEf8,2275
15
- openai_sdk_helpers/response/__init__.py,sha256=Jujf4pD9ilLoiTev07hgzNqiWibd6L_7ZkBCt3addyw,360
16
- openai_sdk_helpers/response/base.py,sha256=Yw6y2mZaH7eF0efyZSMU4cituOmIzKAWeLB9FsVj0gg,18561
17
- openai_sdk_helpers/response/messages.py,sha256=Ot432B9qbbvinGG0aO6mWYeeEUSVqmLiNlvulKbUlZQ,6487
18
- openai_sdk_helpers/response/runner.py,sha256=8OuTxww-GZoJiv6RmjGvavLmmTivXKxkmsx8mSlwhxQ,988
19
- openai_sdk_helpers/response/tool_call.py,sha256=kYUfkjmkLbEJun_QByMuAvYjdixwoRAjHNy2Sk_riXA,1937
20
- openai_sdk_helpers/structure/__init__.py,sha256=SNKpaZ8P9aIZTrBdss2q3r3ZNd74jDCeBMOoS3RJkms,1573
21
- openai_sdk_helpers/structure/base.py,sha256=3UNKeoc7Tm_4vVYdlYuBuizWqKeBa9rQYnzLQcfvx1g,18607
22
- openai_sdk_helpers/structure/prompt.py,sha256=Yovho9WA1AZP1FhKBieBpVThrUn62g4k40mxNrBoY9s,582
23
- openai_sdk_helpers/structure/responses.py,sha256=2Tp_EKmsXoyJolxxsVHIZ3NkPRchONFNbzhEHSXjOww,4188
24
- openai_sdk_helpers/structure/summary.py,sha256=zYRKuBjZHz0GvLRofvJdfD9u101xKgVhFc5CZIlscUE,1682
25
- openai_sdk_helpers/structure/vector_search.py,sha256=b8h2-8kkSc63upGpexLvztqadmlsXulG0MbrtfP-Jvw,2254
26
- openai_sdk_helpers/structure/web_search.py,sha256=XGJS5S-a0t62k7y8r65JzCEdIQh_5dr10EPT-k134Ys,1371
27
- openai_sdk_helpers/structure/plan/__init__.py,sha256=fPGw7xBDVGoqH9x_5Qsu6HeqzY4YZC59e0plEg40DBo,271
28
- openai_sdk_helpers/structure/plan/enum.py,sha256=Ufdhvt-xOkEV5MD3kE60L66NZtGV1bg26opdm-KKV_Y,1076
29
- openai_sdk_helpers/structure/plan/plan.py,sha256=M3PRzoK2n-wHw9mjy2dEAdRVG2N7gv_fezdo6QuPFko,2226
30
- openai_sdk_helpers/structure/plan/task.py,sha256=GvUtruRycxKVmYbJrYY07KseuMeqFsRvQ-_55egsRB8,3501
31
- openai_sdk_helpers/utils/__init__.py,sha256=jaItJ51pCLNGHzG3C2H0sPF1cV1h2BfXYqzGRUH1bO0,294
32
- openai_sdk_helpers/utils/core.py,sha256=rYlfz-F9Ms_eppF2ttCJBpUKoNN8caZPX7iZRJ1uo5Q,5567
33
- openai_sdk_helpers/vector_storage/__init__.py,sha256=BjUueFnxmF4T6YOCra2nqa8rEAzsihEYWavkYB7S_lM,384
34
- openai_sdk_helpers/vector_storage/cleanup.py,sha256=6e_A9MAOKhJl_9EbRgGiB0NrrN79IwN0mMnHrwp4gd8,2964
35
- openai_sdk_helpers/vector_storage/storage.py,sha256=l0keUiKmQPnCl5OGCbV1Fi5hN4F6P_puW3EdAFK4uKE,16927
36
- openai_sdk_helpers/vector_storage/types.py,sha256=9u5oBxKTDf_ljvbWhp1dWVW1zrlVwLd4OpikygvlKJI,1298
37
- openai_sdk_helpers-0.0.2.dist-info/METADATA,sha256=Z5TSH1q-PH8cMb5vZtzWRnKFxgc8YcKAgEJzQEpph7w,4075
38
- openai_sdk_helpers-0.0.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
39
- openai_sdk_helpers-0.0.2.dist-info/licenses/LICENSE,sha256=CUhc1NrE50bs45tcXF7OcTQBKEvkUuLqeOHgrWQ5jaA,1067
40
- openai_sdk_helpers-0.0.2.dist-info/RECORD,,