openai-sdk-helpers 0.1.0__py3-none-any.whl → 0.1.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.
Files changed (44) hide show
  1. openai_sdk_helpers/__init__.py +44 -7
  2. openai_sdk_helpers/agent/base.py +5 -1
  3. openai_sdk_helpers/agent/coordination.py +4 -5
  4. openai_sdk_helpers/agent/runner.py +4 -1
  5. openai_sdk_helpers/agent/search/base.py +1 -0
  6. openai_sdk_helpers/agent/search/vector.py +2 -0
  7. openai_sdk_helpers/cli.py +265 -0
  8. openai_sdk_helpers/config.py +93 -2
  9. openai_sdk_helpers/context_manager.py +1 -1
  10. openai_sdk_helpers/deprecation.py +167 -0
  11. openai_sdk_helpers/environment.py +3 -2
  12. openai_sdk_helpers/errors.py +0 -12
  13. openai_sdk_helpers/files_api.py +373 -0
  14. openai_sdk_helpers/logging_config.py +24 -95
  15. openai_sdk_helpers/prompt/base.py +1 -1
  16. openai_sdk_helpers/response/__init__.py +7 -3
  17. openai_sdk_helpers/response/base.py +217 -147
  18. openai_sdk_helpers/response/config.py +16 -1
  19. openai_sdk_helpers/response/files.py +392 -0
  20. openai_sdk_helpers/response/messages.py +1 -0
  21. openai_sdk_helpers/retry.py +1 -1
  22. openai_sdk_helpers/streamlit_app/app.py +97 -7
  23. openai_sdk_helpers/streamlit_app/streamlit_web_search.py +15 -8
  24. openai_sdk_helpers/structure/base.py +6 -6
  25. openai_sdk_helpers/structure/plan/helpers.py +1 -0
  26. openai_sdk_helpers/structure/plan/task.py +7 -7
  27. openai_sdk_helpers/tools.py +116 -13
  28. openai_sdk_helpers/utils/__init__.py +100 -35
  29. openai_sdk_helpers/{async_utils.py → utils/async_utils.py} +5 -6
  30. openai_sdk_helpers/utils/coercion.py +138 -0
  31. openai_sdk_helpers/utils/deprecation.py +167 -0
  32. openai_sdk_helpers/utils/encoding.py +189 -0
  33. openai_sdk_helpers/utils/json_utils.py +98 -0
  34. openai_sdk_helpers/utils/output_validation.py +448 -0
  35. openai_sdk_helpers/utils/path_utils.py +46 -0
  36. openai_sdk_helpers/{validation.py → utils/validation.py} +7 -3
  37. openai_sdk_helpers/vector_storage/storage.py +59 -28
  38. {openai_sdk_helpers-0.1.0.dist-info → openai_sdk_helpers-0.1.2.dist-info}/METADATA +152 -3
  39. openai_sdk_helpers-0.1.2.dist-info/RECORD +79 -0
  40. openai_sdk_helpers-0.1.2.dist-info/entry_points.txt +2 -0
  41. openai_sdk_helpers/utils/core.py +0 -596
  42. openai_sdk_helpers-0.1.0.dist-info/RECORD +0 -69
  43. {openai_sdk_helpers-0.1.0.dist-info → openai_sdk_helpers-0.1.2.dist-info}/WHEEL +0 -0
  44. {openai_sdk_helpers-0.1.0.dist-info → openai_sdk_helpers-0.1.2.dist-info}/licenses/LICENSE +0 -0
@@ -12,7 +12,8 @@ import logging
12
12
  import mimetypes
13
13
  import os
14
14
  from concurrent.futures import ThreadPoolExecutor, as_completed
15
- from typing import cast
15
+ from pathlib import Path
16
+ from typing import Any, cast
16
17
 
17
18
  from openai import OpenAI
18
19
  from openai.pagination import SyncPage
@@ -20,8 +21,10 @@ from openai.types.vector_store import VectorStore
20
21
  from openai.types.vector_store_search_response import VectorStoreSearchResponse
21
22
  from tqdm import tqdm
22
23
 
24
+ from ..config import OpenAISettings
25
+ from ..errors import ConfigurationError, VectorStorageError
23
26
  from ..types import OpenAIClient
24
- from ..utils import ensure_list, log
27
+ from ..utils import ensure_list, ensure_directory, log
25
28
  from .types import VectorStorageFileInfo, VectorStorageFileStats
26
29
 
27
30
  TEXT_MIME_PREFIXES = ("text/",)
@@ -96,6 +99,7 @@ class VectorStorage:
96
99
 
97
100
  def __init__(
98
101
  self,
102
+ *,
99
103
  store_name: str,
100
104
  client: OpenAIClient | None = None,
101
105
  model: str | None = None,
@@ -118,26 +122,21 @@ class VectorStorage:
118
122
 
119
123
  Raises
120
124
  ------
121
- ValueError
125
+ ConfigurationError
122
126
  If no API key or embedding model can be resolved.
123
- RuntimeError
124
- If the OpenAI client cannot be initialized.
125
127
  """
126
- self._client: OpenAIClient
127
128
  if client is None:
128
- api_key = os.getenv("OPENAI_API_KEY")
129
- if api_key is None:
130
- raise ValueError("OpenAI API key is required")
131
129
  try:
132
- self._client = OpenAI(api_key=api_key)
133
- except Exception as exc:
134
- raise RuntimeError("Failed to initialize OpenAI client") from exc
130
+ settings = OpenAISettings.from_env()
131
+ self._client = settings.create_client()
132
+ except ValueError as exc:
133
+ raise ConfigurationError(str(exc)) from exc
135
134
  else:
136
135
  self._client = client
137
136
 
138
137
  self._model = model or os.getenv("OPENAI_MODEL")
139
138
  if self._model is None:
140
- raise ValueError("OpenAI model is required")
139
+ raise ConfigurationError("OpenAI model is required")
141
140
 
142
141
  self._vector_storage = self._get_or_create_vector_storage(store_name)
143
142
  self._existing_files: dict[str, str] | None = {}
@@ -228,10 +227,12 @@ class VectorStorage:
228
227
  def upload_file(
229
228
  self,
230
229
  file_path: str,
230
+ *,
231
231
  purpose: str = "assistants",
232
232
  attributes: dict[str, str | float | bool] | None = None,
233
233
  overwrite: bool = False,
234
234
  refresh_cache: bool = False,
235
+ expires_after: int | None = None,
235
236
  ) -> VectorStorageFileInfo:
236
237
  """Upload a single file to the vector store.
237
238
 
@@ -253,6 +254,9 @@ class VectorStorage:
253
254
  refresh_cache : bool, optional
254
255
  When True, refresh the local cache of existing files before
255
256
  checking for duplicates, by default False.
257
+ expires_after : int or None, optional
258
+ Number of seconds after which the file expires and is deleted.
259
+ If None and purpose is "user_data", defaults to 86400 (24 hours).
256
260
 
257
261
  Returns
258
262
  -------
@@ -263,6 +267,10 @@ class VectorStorage:
263
267
  attributes = dict(attributes or {})
264
268
  attributes["file_name"] = file_name
265
269
 
270
+ # Default to 24 hours expiration for user_data files
271
+ if expires_after is None and purpose == "user_data":
272
+ expires_after = 86400 # 24 hours in seconds
273
+
266
274
  if refresh_cache:
267
275
  self._existing_files = self._load_existing_files()
268
276
 
@@ -291,7 +299,9 @@ class VectorStorage:
291
299
  file_data = handle.read()
292
300
 
293
301
  file = self._client.files.create(
294
- file=(file_path, file_data), purpose=purpose # type: ignore
302
+ file=(file_name, file_data),
303
+ purpose=cast(Any, purpose), # Cast to avoid type error
304
+ expires_after=expires_after, # type: ignore
295
305
  )
296
306
 
297
307
  self._client.vector_stores.files.create(
@@ -316,9 +326,11 @@ class VectorStorage:
316
326
  def upload_files(
317
327
  self,
318
328
  file_patterns: str | list[str],
329
+ *,
319
330
  purpose: str = "assistants",
320
331
  attributes: dict[str, str | float | bool] | None = None,
321
332
  overwrite: bool = False,
333
+ expires_after: int | None = None,
322
334
  ) -> VectorStorageFileStats:
323
335
  """Upload files matching glob patterns using a thread pool.
324
336
 
@@ -337,6 +349,9 @@ class VectorStorage:
337
349
  overwrite : bool, optional
338
350
  When True, re-upload files even if files with the same name
339
351
  exist, by default False.
352
+ expires_after : int or None, optional
353
+ Number of seconds after which files expire and are deleted.
354
+ If None and purpose is "user_data", defaults to 86400 (24 hours).
340
355
 
341
356
  Returns
342
357
  -------
@@ -369,10 +384,11 @@ class VectorStorage:
369
384
  executor.submit(
370
385
  self.upload_file,
371
386
  path,
372
- purpose,
373
- attributes,
374
- overwrite,
375
- False,
387
+ purpose=purpose,
388
+ attributes=attributes,
389
+ overwrite=overwrite,
390
+ refresh_cache=False,
391
+ expires_after=expires_after,
376
392
  ): path
377
393
  for path in all_paths
378
394
  }
@@ -390,10 +406,10 @@ class VectorStorage:
390
406
  return stats
391
407
 
392
408
  def delete_file(self, file_id: str) -> VectorStorageFileInfo:
393
- """Delete a specific file from the vector store.
409
+ """Delete a specific file from the vector store and OpenAI Files API.
394
410
 
395
- Removes the file from the vector store and updates the local cache.
396
- The operation is irreversible.
411
+ Removes the file from the vector store, then deletes it from OpenAI's
412
+ Files API storage. Updates the local cache. The operation is irreversible.
397
413
 
398
414
  Parameters
399
415
  ----------
@@ -407,10 +423,22 @@ class VectorStorage:
407
423
  "success" or "failed".
408
424
  """
409
425
  try:
426
+ # First remove from vector store
410
427
  self._client.vector_stores.files.delete(
411
428
  vector_store_id=self._vector_storage.id, file_id=file_id
412
429
  )
413
430
 
431
+ # Then delete the actual file from OpenAI storage
432
+ try:
433
+ self._client.files.delete(file_id)
434
+ log(f"Deleted file {file_id} from OpenAI Files API")
435
+ except Exception as file_delete_exc:
436
+ # Log but don't fail if file doesn't exist or can't be deleted
437
+ log(
438
+ f"Warning: Could not delete file {file_id} from Files API: {file_delete_exc}",
439
+ level=logging.WARNING,
440
+ )
441
+
414
442
  to_remove = [k for k, v in self.existing_files.items() if v == file_id]
415
443
  for key in to_remove:
416
444
  del self.existing_files[key]
@@ -463,16 +491,19 @@ class VectorStorage:
463
491
  def delete(self) -> None:
464
492
  """Delete the entire vector store and all associated files.
465
493
 
466
- Removes each file individually before deleting the store itself.
467
- The local cache is cleared after deletion.
494
+ Removes each file from the vector store and deletes it from OpenAI's
495
+ Files API storage before deleting the store itself. The local cache
496
+ is cleared after deletion.
468
497
 
469
498
  Warning: This operation is irreversible and will permanently delete
470
- the vector store and all its files.
499
+ the vector store and all its files from OpenAI storage.
471
500
  """
472
501
  try:
473
502
  existing_files = list(self.existing_files.items())
474
503
  for file_name, file_id in existing_files:
475
- log(f"Deleting file {file_id} ({file_name}) from vector store")
504
+ log(
505
+ f"Deleting file {file_id} ({file_name}) from vector store and Files API"
506
+ )
476
507
  self.delete_file(file_id)
477
508
 
478
509
  self._client.vector_stores.delete(self._vector_storage.id)
@@ -502,7 +533,7 @@ class VectorStorage:
502
533
  VectorStorageFileStats
503
534
  Aggregated statistics describing the download results.
504
535
  """
505
- os.makedirs(output_dir, exist_ok=True)
536
+ ensure_directory(Path(output_dir))
506
537
 
507
538
  try:
508
539
  files = self._client.vector_stores.files.list(
@@ -552,7 +583,7 @@ class VectorStorage:
552
583
  return stats
553
584
 
554
585
  def search(
555
- self, query: str, top_k: int = 5
586
+ self, query: str, *, top_k: int = 5
556
587
  ) -> SyncPage[VectorStoreSearchResponse] | None:
557
588
  """Perform a semantic search within the vector store.
558
589
 
@@ -583,7 +614,7 @@ class VectorStorage:
583
614
  log(f"Error searching vector store: {str(exc)}", level=logging.ERROR)
584
615
  return None
585
616
 
586
- def summarize(self, query: str, top_k: int = 15) -> str | None:
617
+ def summarize(self, query: str, *, top_k: int = 15) -> str | None:
587
618
  """Perform a semantic search and summarize results by topic.
588
619
 
589
620
  Retrieves top search results and generates a summary. This method
@@ -1,14 +1,24 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openai-sdk-helpers
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Composable helpers for OpenAI SDK agents, prompts, and storage
5
5
  Author: openai-sdk-helpers maintainers
6
6
  License: MIT
7
7
  License-File: LICENSE
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
+ Classifier: Typing :: Typed
8
18
  Requires-Python: >=3.10
9
19
  Requires-Dist: jinja2
10
- Requires-Dist: openai
11
- Requires-Dist: openai-agents
20
+ Requires-Dist: openai-agents<1.0.0,>=0.6.4
21
+ Requires-Dist: openai<3.0.0,>=2.14.0
12
22
  Requires-Dist: pydantic<3,>=2.7
13
23
  Requires-Dist: python-dotenv
14
24
  Requires-Dist: streamlit
@@ -90,6 +100,26 @@ The `agent` module provides a higher-level abstraction for building agents, whil
90
100
  - **Tool execution framework** with custom handlers and structured outputs
91
101
  - **Session persistence** for saving and restoring conversation history
92
102
 
103
+ #### Infrastructure & Utilities
104
+ - **Centralized logger factory** for consistent application logging
105
+ - **Retry patterns** with exponential backoff and jitter
106
+ - **Output validation** framework with JSON schema, semantic, and length validators
107
+ - **CLI tool** for testing agents, validating templates, and inspecting registries
108
+ - **Deprecation utilities** for managing API changes
109
+
110
+ #### Shared Components
111
+ - **Typed structures** using Pydantic for prompts, responses, and search workflows
112
+ to ensure predictable inputs and outputs
113
+ - **OpenAI configuration management** with environment variable and `.env` file support
114
+ - **Vector storage abstraction** for seamless integration with OpenAI vector stores
115
+ - **Type-safe interfaces** with full type hints and `py.typed` marker for external projects
116
+ - **ValidatorAgent**: Check inputs and outputs against safety guardrails
117
+
118
+ #### Response Module (Built on `openai` SDK)
119
+ - **Response handling utilities** for direct API control with fine-grained message management
120
+ - **Tool execution framework** with custom handlers and structured outputs
121
+ - **Session persistence** for saving and restoring conversation history
122
+
93
123
  #### Shared Components
94
124
  - **Typed structures** using Pydantic for prompts, responses, and search workflows
95
125
  to ensure predictable inputs and outputs
@@ -276,6 +306,99 @@ response.close()
276
306
 
277
307
  ## Advanced Usage
278
308
 
309
+ ### Image and File Analysis
310
+
311
+ The `response` module automatically detects file types and handles them appropriately:
312
+
313
+ ```python
314
+ from openai_sdk_helpers.response import BaseResponse
315
+ from openai_sdk_helpers import OpenAISettings
316
+
317
+ settings = OpenAISettings.from_env()
318
+
319
+ with BaseResponse(
320
+ name="analyzer",
321
+ instructions="You are a helpful assistant that can analyze files.",
322
+ tools=None,
323
+ output_structure=None,
324
+ tool_handlers={},
325
+ openai_settings=settings,
326
+ ) as response:
327
+ # Automatic type detection - single files parameter
328
+ # Images are sent as base64-encoded images
329
+ # Documents are sent as base64-encoded file data
330
+ result = response.run_sync(
331
+ "Analyze these files",
332
+ files=["photo.jpg", "document.pdf"]
333
+ )
334
+ print(result)
335
+
336
+ # Single file - automatically detected
337
+ result = response.run_sync(
338
+ "What's in this image?",
339
+ files="photo.jpg" # Automatically detected as image
340
+ )
341
+ print(result)
342
+
343
+ # Use vector store for RAG (Retrieval-Augmented Generation)
344
+ result = response.run_sync(
345
+ "Search these documents",
346
+ files=["doc1.pdf", "doc2.pdf"],
347
+ use_vector_store=True # Enable RAG with vector stores
348
+ )
349
+ print(result)
350
+ ```
351
+
352
+ **How It Works:**
353
+
354
+ - **Images** (jpg, png, gif, etc.) are automatically sent as base64-encoded images
355
+ - **Documents** (pdf, txt, xlsx, etc.) are sent as base64-encoded file data by default
356
+ - **Vector Stores** can optionally be used for documents when `use_vector_store=True`
357
+ - **Batch Processing** is automatically used for multiple files (>3) for efficient encoding
358
+
359
+ **Advanced File Processing:**
360
+
361
+ ```python
362
+ from openai_sdk_helpers.response import process_files
363
+
364
+ # Process files directly with the dedicated module
365
+ vector_files, base64_files, images = process_files(
366
+ response,
367
+ files=["photo1.jpg", "photo2.jpg", "doc1.pdf", "doc2.pdf"],
368
+ use_vector_store=False,
369
+ batch_size=20, # Files per batch
370
+ max_workers=10, # Concurrent workers
371
+ )
372
+ ```
373
+
374
+ **Base64 Encoding Utilities:**
375
+
376
+ ```python
377
+ from openai_sdk_helpers.utils import (
378
+ encode_image,
379
+ encode_file,
380
+ is_image_file,
381
+ create_image_data_url,
382
+ create_file_data_url,
383
+ )
384
+
385
+ # Check if a file is an image
386
+ is_image_file("photo.jpg") # True
387
+ is_image_file("document.pdf") # False
388
+
389
+ # Encode an image to base64
390
+ base64_image = encode_image("photo.jpg")
391
+
392
+ # Create a data URL for an image
393
+ image_url, detail = create_image_data_url("photo.jpg", detail="high")
394
+
395
+ # Encode a file to base64
396
+ base64_file = encode_file("document.pdf")
397
+
398
+ # Create a data URL for a file
399
+ file_data = create_file_data_url("document.pdf")
400
+ ```
401
+
279
402
  ### Custom Prompt Templates
280
403
 
281
404
  Create custom Jinja2 templates for specialized agent behaviors:
@@ -502,6 +625,31 @@ See `AGENTS.md` for detailed contributing guidelines and conventions.
502
625
  This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
503
626
  for details.
504
627
 
628
+ ## CLI Tool
629
+
630
+ The package includes a command-line tool for development and testing:
631
+
632
+ ```bash
633
+ # List all registered response configurations
634
+ openai-helpers registry list
635
+
636
+ # Inspect a specific configuration
637
+ openai-helpers registry inspect my_config
638
+
639
+ # Validate Jinja2 templates
640
+ openai-helpers template validate ./templates
641
+
642
+ # Test an agent (coming soon)
643
+ openai-helpers agent test MyAgent --input "test input"
644
+ ```
645
+
646
+ ### CLI Commands
647
+
648
+ - **registry list** - Show all registered response configurations
649
+ - **registry inspect** - Display details of a configuration
650
+ - **template validate** - Check template syntax and structure
651
+ - **agent test** - Test agents locally with sample inputs
652
+
505
653
  ## Troubleshooting
506
654
 
507
655
  ### Common Issues
@@ -523,6 +671,7 @@ OPENAI_API_KEY=your-api-key-here
523
671
  Vector search workflows require custom prompt templates. Either:
524
672
  1. Create the required `.jinja` files in your `prompt_dir`
525
673
  2. Omit the `prompt_dir` parameter to use built-in defaults (for text agents only)
674
+ 3. Use the CLI to validate templates: `openai-helpers template validate ./templates`
526
675
 
527
676
  **Import errors after installation**
528
677
 
@@ -0,0 +1,79 @@
1
+ openai_sdk_helpers/__init__.py,sha256=rsCoQ2yB8jJmWZxbXeXTf0dPcyWJIzghCS_CVPkBWKg,4626
2
+ openai_sdk_helpers/cli.py,sha256=J62XKPkGgYzYHKHfnkFy53Dp4rvBXf9cPEl1hrev3ZU,7400
3
+ openai_sdk_helpers/config.py,sha256=pjBzjYM9Fs4DQqwio387lBt_4IwWKct_VNZBSe-bMqg,10972
4
+ openai_sdk_helpers/context_manager.py,sha256=QqlrtenwKoz2krY0IzuToKdTX1HptUYtIEylxieybgY,6633
5
+ openai_sdk_helpers/deprecation.py,sha256=VF0VDDegawYhsu5f-vE6dop9ob-jv8egxsm0KsPvP9E,4753
6
+ openai_sdk_helpers/environment.py,sha256=RBYpRFamclaom07msipJ7jnnPkfVqjl1PRhDE5phZdg,1401
7
+ openai_sdk_helpers/errors.py,sha256=0TLrcpRXPBvk2KlrU5I1VAQl-sYy-d15h_SMDkEawvI,2757
8
+ openai_sdk_helpers/files_api.py,sha256=cNZObACSDX52kUvUOwanPyFqXcqRJe8D8_iB6AFqC2c,11810
9
+ openai_sdk_helpers/logging_config.py,sha256=JcR0FTWht1tYdwD-bXH835pr0JV0RwHfY3poruiZGHM,795
10
+ openai_sdk_helpers/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ openai_sdk_helpers/retry.py,sha256=J10oQYphfzDXm3BnLoXwxk7PAhN93TC2LQOv0VDGOwI,6533
12
+ openai_sdk_helpers/tools.py,sha256=C2xl0euovFyrDVh0qf1pEyuaicmrTmoZcJu9CxCKqic,9534
13
+ openai_sdk_helpers/types.py,sha256=xzldCRfwCZ3rZl18IBmfgA-PVdoZKSWNrlSIhirumSo,1451
14
+ openai_sdk_helpers/agent/__init__.py,sha256=giowU8jke0z0h7FFUG9V6Vssja8AYwvJMQbiMb3s64k,960
15
+ openai_sdk_helpers/agent/base.py,sha256=8ZkW57vL8_fYzuLr6f9kMvBChYq5lN5vQ8MMJtcWD9s,11784
16
+ openai_sdk_helpers/agent/config.py,sha256=htqy5bcrJeMf3rIpRdL9CKlYwyQI4po420rcgR3i8XI,1971
17
+ openai_sdk_helpers/agent/coordination.py,sha256=knhQtOyQGGkqKb6Q-pWSRwrVW0qJcVvxelinIctNs-A,16152
18
+ openai_sdk_helpers/agent/prompt_utils.py,sha256=-1M66tqQxh9wWCFg6X-K7cCcqauca3yA04ZjvOpN3bA,337
19
+ openai_sdk_helpers/agent/runner.py,sha256=1_azIWx1Bcy7RRlEbizTD0LXBdYgof_tYMpDUcnJJuM,4164
20
+ openai_sdk_helpers/agent/summarizer.py,sha256=fH8AnYK_68ERf2U7mv0nwXL8KyhrluE-TDY_M5TCdD0,3266
21
+ openai_sdk_helpers/agent/translator.py,sha256=GhUuwFTBecgOO9pMQ41VPvK9mTub5DXJ_7BIS9Xp7bs,5082
22
+ openai_sdk_helpers/agent/utils.py,sha256=DTD5foCqGYfXf13F2bZMYIQROl7SbDSy5GDPGi0Zl-0,1089
23
+ openai_sdk_helpers/agent/validation.py,sha256=JIYVhBTTs0tTxYyzYgY3BHC-9psyzE3LLQDZDqpg13M,4191
24
+ openai_sdk_helpers/agent/search/__init__.py,sha256=xqosfzH4HcBs9IFZks9msG_694rS5q6Ea4_qNeRQRmU,798
25
+ openai_sdk_helpers/agent/search/base.py,sha256=EP4WCIC-IItToTFVRVpg1pj1PC5QtqheIiK1l087yRg,8613
26
+ openai_sdk_helpers/agent/search/vector.py,sha256=xMWhuRQENdWfLN1NTBzEjMfq1WsaGS6yn70-Xq9oFj4,13622
27
+ openai_sdk_helpers/agent/search/web.py,sha256=8le4xnZ3nllySqWb7rZaOq44ZR8q67c_WiE57ncmL90,10014
28
+ openai_sdk_helpers/enums/__init__.py,sha256=aFf79C4JBeLC3kMlJfSpehyjx5uNCtW6eK5rD6ZFfhM,322
29
+ openai_sdk_helpers/enums/base.py,sha256=cNllDtzcgI0_eZYXxFko14yhxwicX6xbeDfz9gFE3qo,2753
30
+ openai_sdk_helpers/prompt/__init__.py,sha256=MOqgKwG9KLqKudoKRlUfLxiSmdOi2aD6hNrWDFqLHkk,418
31
+ openai_sdk_helpers/prompt/base.py,sha256=o-O5S-et4mE30_LkFPzL3o67Z_3KrLFG55gQDlL4vqE,7575
32
+ openai_sdk_helpers/prompt/summarizer.jinja,sha256=jliSetWDISbql1EkWi1RB8-L_BXUg8JMkRRsPRHuzbY,309
33
+ openai_sdk_helpers/prompt/translator.jinja,sha256=SZhW8ipEzM-9IA4wyS_r2wIMTAclWrilmk1s46njoL0,291
34
+ openai_sdk_helpers/prompt/validator.jinja,sha256=6t8q_IdxFd3mVBGX6SFKNOert1Wo3YpTOji2SNEbbtE,547
35
+ openai_sdk_helpers/response/__init__.py,sha256=td-HTSPLtl1d5AkUFZ0rrUBUfsacM_CGtZQNj1_GWB8,1886
36
+ openai_sdk_helpers/response/base.py,sha256=rDzFBLl8hU1Rho7SfLUcd0eQLRpn1ZRAvvzXDqdWf0c,29854
37
+ openai_sdk_helpers/response/config.py,sha256=zZ4w2-GTSKg-7XgK6iUb5pDK-5aBFd2WkvbIjvegyHU,10871
38
+ openai_sdk_helpers/response/files.py,sha256=ANCoedNHXmpTXSaaGUvesAGq2DIUXT7SKZDCIJlXOv8,13226
39
+ openai_sdk_helpers/response/messages.py,sha256=G4V8a9gis4b8wFW5XnvBE0AHMX0FrkOzqiQ6FxigpnU,9145
40
+ openai_sdk_helpers/response/runner.py,sha256=Rf13cQGsR7sN9gA81Y5th1tfH2DCCAwQ6RMs3bVgjnk,4269
41
+ openai_sdk_helpers/response/tool_call.py,sha256=VYPvKUR-Ren0Y_nYS4jUSinhTyXKzFwQLxu-d3r_YuM,4506
42
+ openai_sdk_helpers/response/vector_store.py,sha256=MyHUu6P9ueNsd9erbBkyVqq3stLK6qVuehdvmFAHq9E,3074
43
+ openai_sdk_helpers/streamlit_app/__init__.py,sha256=RjJbnBDS5_YmAmxvaa3phB5u9UcXsXDEk_jMlY_pa5Q,793
44
+ openai_sdk_helpers/streamlit_app/app.py,sha256=Sm9010pfrNlobF-ah-GKepob8slFEv1kEI_6-61R4O8,13690
45
+ openai_sdk_helpers/streamlit_app/config.py,sha256=EK6LWACo7YIkDko1oesvupOx56cTuWWnwnXRiu8EYbs,15986
46
+ openai_sdk_helpers/streamlit_app/streamlit_web_search.py,sha256=0RjB545dIvEeZiiLWM7C4CufbD3DITOWLZEVgxAL6mo,2812
47
+ openai_sdk_helpers/structure/__init__.py,sha256=QUvRdJMbKsumjwJdWq9ihfcOED4ZbJMBQbmA1nmYJVw,3339
48
+ openai_sdk_helpers/structure/agent_blueprint.py,sha256=2W-RBM5G3ZefMcYHqqoV6Y1witcSbMlUpdU1CA9n3tg,9698
49
+ openai_sdk_helpers/structure/base.py,sha256=i937ZjMqTcdFd8UQXcA1sv-Lz1WJZlweGd-qLdD8TQE,28322
50
+ openai_sdk_helpers/structure/prompt.py,sha256=7DBdLu6WDvXy2RkEBayDiX2Jn8T4-hJuohsOaKEoqJs,1075
51
+ openai_sdk_helpers/structure/responses.py,sha256=iYJBT_4VFifzQqPnTpRWTcB0o7xkhPIQ2ugedivrpto,4868
52
+ openai_sdk_helpers/structure/summary.py,sha256=MyZzMuqHP9F8B4rYYxCGJwojy5RavWUkMiRZ6yMQzvU,3143
53
+ openai_sdk_helpers/structure/validation.py,sha256=vsilA3Qs3fjWLeYlnZnMEGj9i_bOJtXc2J3mSIEHncg,2409
54
+ openai_sdk_helpers/structure/vector_search.py,sha256=A0w2AR0r6aIFoYbNkscUAGT7VzTe6WuvxrqUsWT2PMQ,5782
55
+ openai_sdk_helpers/structure/web_search.py,sha256=S8OdllBWqEGXaKf6Alocl89ZuG7BlvXK5ra1Lm7lfjE,4572
56
+ openai_sdk_helpers/structure/plan/__init__.py,sha256=IGr0Tk4inN_8o7fT2N02_FTi6U6l2T9_npcQHAlBwKA,1076
57
+ openai_sdk_helpers/structure/plan/enum.py,sha256=seESSwH-IeeW-9BqIMUQyk3qjtchfU3TDhF9HPDB1OM,3079
58
+ openai_sdk_helpers/structure/plan/helpers.py,sha256=Vc6dBTMFrNWlsaCTpEImEIKjfFq4BSSxNjB4K8dywOQ,5139
59
+ openai_sdk_helpers/structure/plan/plan.py,sha256=LtfwWwZiHGe06nFCXSbT8p3x3w9hhI0wXS7hTeeWXvY,9663
60
+ openai_sdk_helpers/structure/plan/task.py,sha256=R2MInXiOWvs5zFGVOfAhVivRxXWTBp8NrmVpZ7aUmM8,4580
61
+ openai_sdk_helpers/structure/plan/types.py,sha256=7y9QEVdZreQUXV7n-R4RoNZzw5HeOVbJGWx9QkSfuNY,418
62
+ openai_sdk_helpers/utils/__init__.py,sha256=UauMvn_2klGxXlz2Sn0RwJB1tIEkg7p0Qm9J8zaZFlM,3289
63
+ openai_sdk_helpers/utils/async_utils.py,sha256=9KbPEVfi6IXdbwkTUE0h5DleK8TI7I6P_VPL8UgUv98,3689
64
+ openai_sdk_helpers/utils/coercion.py,sha256=Pq1u7tAbD7kTZ84lK-7Fb9CyYKKKQt4fypG5BlSI6oQ,3774
65
+ openai_sdk_helpers/utils/deprecation.py,sha256=VF0VDDegawYhsu5f-vE6dop9ob-jv8egxsm0KsPvP9E,4753
66
+ openai_sdk_helpers/utils/encoding.py,sha256=oDtlNGZ5p-edXiHW76REs-0-8NXkQNReKJdj6sHLkt8,4615
67
+ openai_sdk_helpers/utils/json_utils.py,sha256=dpv0IPZp4WKL7HsDAQY2za820ukn0cre6kAv-pYw7P0,3141
68
+ openai_sdk_helpers/utils/output_validation.py,sha256=O9Adt-fxL5DtnMd1GuZ9E2YxX3yj4uzSZuBNKVH2GkI,12152
69
+ openai_sdk_helpers/utils/path_utils.py,sha256=qGGDpuDnY5EODOACzH23MYECQOE2rKhrQ3sbDvefwEg,1307
70
+ openai_sdk_helpers/utils/validation.py,sha256=ZjnZNOy5AoFlszRxarNol6YZwfgw6LnwPtkCekZmwAU,7826
71
+ openai_sdk_helpers/vector_storage/__init__.py,sha256=L5LxO09puh9_yBB9IDTvc1CvVkARVkHqYY1KX3inB4c,975
72
+ openai_sdk_helpers/vector_storage/cleanup.py,sha256=ImWIE-9lli-odD8qIARvmeaa0y8ZD4pYYP-kT0O3178,3552
73
+ openai_sdk_helpers/vector_storage/storage.py,sha256=1juu3Qq6hy33afvVfQeI5A35fQzIPjVZumZ-aP_MxhU,23305
74
+ openai_sdk_helpers/vector_storage/types.py,sha256=jTCcOYMeOpZWvcse0z4T3MVs-RBOPC-fqWTBeQrgafU,1639
75
+ openai_sdk_helpers-0.1.2.dist-info/METADATA,sha256=3nSHx2-Xs0U_2Y1DHYcntmSkHmGEEYBonXbfFi2OINo,23557
76
+ openai_sdk_helpers-0.1.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
77
+ openai_sdk_helpers-0.1.2.dist-info/entry_points.txt,sha256=gEOD1ZeXe8d2OP-KzUlG-b_9D9yUZTCt-GFW3EDbIIY,63
78
+ openai_sdk_helpers-0.1.2.dist-info/licenses/LICENSE,sha256=CUhc1NrE50bs45tcXF7OcTQBKEvkUuLqeOHgrWQ5jaA,1067
79
+ openai_sdk_helpers-0.1.2.dist-info/RECORD,,
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ openai-helpers = openai_sdk_helpers.cli:main