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
@@ -1,596 +0,0 @@
1
- """Core utility helpers for openai-sdk-helpers.
2
-
3
- This module provides foundational utility functions for type coercion,
4
- file path validation, JSON serialization, and logging. These utilities
5
- support consistent data handling across the package.
6
- """
7
-
8
- from __future__ import annotations
9
-
10
- import json
11
- import logging
12
- import ast
13
- from collections.abc import Iterable, Mapping
14
- from dataclasses import asdict, is_dataclass
15
- from datetime import datetime
16
- from enum import Enum
17
- from pathlib import Path
18
- from typing import Any, TypeVar
19
-
20
-
21
- def coerce_optional_float(value: object) -> float | None:
22
- """Return a float when the provided value can be coerced, otherwise None.
23
-
24
- Handles float, int, and string inputs. Empty strings or None return None.
25
-
26
- Parameters
27
- ----------
28
- value : object
29
- Value to convert into a float. Strings must be parseable as floats.
30
-
31
- Returns
32
- -------
33
- float or None
34
- Converted float value or None if the input is None.
35
-
36
- Raises
37
- ------
38
- ValueError
39
- If a non-empty string cannot be converted to a float.
40
- TypeError
41
- If the value is not a float-compatible type.
42
-
43
- Examples
44
- --------
45
- >>> coerce_optional_float(3.14)
46
- 3.14
47
- >>> coerce_optional_float("2.5")
48
- 2.5
49
- >>> coerce_optional_float(None) is None
50
- True
51
- """
52
- if value is None:
53
- return None
54
- if isinstance(value, (float, int)):
55
- return float(value)
56
- if isinstance(value, str) and value.strip():
57
- try:
58
- return float(value)
59
- except ValueError as exc:
60
- raise ValueError("timeout must be a float-compatible value") from exc
61
- raise TypeError("timeout must be a float, int, str, or None")
62
-
63
-
64
- def coerce_optional_int(value: object) -> int | None:
65
- """Return an int when the provided value can be coerced, otherwise None.
66
-
67
- Handles int, float (if whole number), and string inputs. Empty strings
68
- or None return None. Booleans are not considered valid integers.
69
-
70
- Parameters
71
- ----------
72
- value : object
73
- Value to convert into an int. Strings must be parseable as integers.
74
-
75
- Returns
76
- -------
77
- int or None
78
- Converted integer value or None if the input is None.
79
-
80
- Raises
81
- ------
82
- ValueError
83
- If a non-empty string cannot be converted to an integer.
84
- TypeError
85
- If the value is not an int-compatible type.
86
-
87
- Examples
88
- --------
89
- >>> coerce_optional_int(42)
90
- 42
91
- >>> coerce_optional_int("100")
92
- 100
93
- >>> coerce_optional_int(3.0)
94
- 3
95
- >>> coerce_optional_int(None) is None
96
- True
97
- """
98
- if value is None:
99
- return None
100
- if isinstance(value, int) and not isinstance(value, bool):
101
- return value
102
- if isinstance(value, float) and value.is_integer():
103
- return int(value)
104
- if isinstance(value, str) and value.strip():
105
- try:
106
- return int(value)
107
- except ValueError as exc:
108
- raise ValueError("max_retries must be an int-compatible value") from exc
109
- raise TypeError("max_retries must be an int, str, or None")
110
-
111
-
112
- def coerce_dict(value: object) -> dict[str, Any]:
113
- """Return a string-keyed dictionary built from value if possible.
114
-
115
- Converts Mapping objects to dictionaries. None returns an empty dict.
116
-
117
- Parameters
118
- ----------
119
- value : object
120
- Mapping-like value to convert. None yields an empty dictionary.
121
-
122
- Returns
123
- -------
124
- dict[str, Any]
125
- Dictionary representation of value.
126
-
127
- Raises
128
- ------
129
- TypeError
130
- If the value cannot be treated as a mapping.
131
-
132
- Examples
133
- --------
134
- >>> coerce_dict({"a": 1})
135
- {'a': 1}
136
- >>> coerce_dict(None)
137
- {}
138
- """
139
- if value is None:
140
- return {}
141
- if isinstance(value, Mapping):
142
- return dict(value)
143
- raise TypeError("extra_client_kwargs must be a mapping or None")
144
-
145
-
146
- def build_openai_settings(
147
- api_key: str | None = None,
148
- org_id: str | None = None,
149
- project_id: str | None = None,
150
- base_url: str | None = None,
151
- default_model: str | None = None,
152
- timeout: float | str | None = None,
153
- max_retries: int | str | None = None,
154
- dotenv_path: Path | None = None,
155
- **extra_kwargs: Any,
156
- ) -> Any: # Returns OpenAISettings but use Any to avoid circular import
157
- """Build OpenAI settings from environment with explicit validation.
158
-
159
- Convenience function for creating OpenAISettings with validation and
160
- clear error messages. Reads from environment variables and validates
161
- required fields, with explicit type coercion for timeout and max_retries.
162
-
163
- Parameters
164
- ----------
165
- api_key : str or None, default None
166
- API key for OpenAI authentication. If None, reads from OPENAI_API_KEY.
167
- org_id : str or None, default None
168
- Organization ID. If None, reads from OPENAI_ORG_ID.
169
- project_id : str or None, default None
170
- Project ID. If None, reads from OPENAI_PROJECT_ID.
171
- base_url : str or None, default None
172
- Base URL for API requests. If None, reads from OPENAI_BASE_URL.
173
- default_model : str or None, default None
174
- Default model name. If None, reads from OPENAI_MODEL.
175
- timeout : float, str, or None, default None
176
- Request timeout in seconds. If None, reads from OPENAI_TIMEOUT.
177
- Can be string that will be parsed to float.
178
- max_retries : int, str, or None, default None
179
- Maximum retry attempts. If None, reads from OPENAI_MAX_RETRIES.
180
- Can be string that will be parsed to int.
181
- dotenv_path : Path or None, default None
182
- Path to .env file. If None, searches for .env in current directory.
183
- **extra_kwargs : Any
184
- Additional keyword arguments for extra_client_kwargs.
185
-
186
- Returns
187
- -------
188
- OpenAISettings
189
- Configured settings instance.
190
-
191
- Raises
192
- ------
193
- ValueError
194
- If OPENAI_API_KEY is not found in environment or parameters.
195
- If timeout cannot be parsed as float.
196
- If max_retries cannot be parsed as int.
197
- TypeError
198
- If timeout or max_retries have invalid types.
199
-
200
- Examples
201
- --------
202
- Build from explicit parameters:
203
-
204
- >>> settings = build_openai_settings(
205
- ... api_key="sk-...",
206
- ... default_model="gpt-4o",
207
- ... timeout=30.0
208
- ... )
209
-
210
- Build from environment:
211
-
212
- >>> settings = build_openai_settings() # doctest: +SKIP
213
-
214
- With custom .env location:
215
-
216
- >>> settings = build_openai_settings(
217
- ... dotenv_path=Path("/path/to/.env")
218
- ... ) # doctest: +SKIP
219
- """
220
- # Import at runtime to avoid circular import
221
- from openai_sdk_helpers.config import OpenAISettings
222
-
223
- # Parse timeout with validation
224
- parsed_timeout: float | None = None
225
- if timeout is not None:
226
- try:
227
- parsed_timeout = coerce_optional_float(timeout)
228
- except (ValueError, TypeError) as exc:
229
- raise ValueError(
230
- f"Invalid timeout value '{timeout}'. Must be a number or numeric string."
231
- ) from exc
232
-
233
- # Parse max_retries with validation
234
- parsed_max_retries: int | None = None
235
- if max_retries is not None:
236
- try:
237
- parsed_max_retries = coerce_optional_int(max_retries)
238
- except (ValueError, TypeError) as exc:
239
- raise ValueError(
240
- f"Invalid max_retries value '{max_retries}'. "
241
- "Must be an integer or numeric string."
242
- ) from exc
243
-
244
- # Build settings using from_env with overrides
245
- overrides = {}
246
- if api_key is not None:
247
- overrides["api_key"] = api_key
248
- if org_id is not None:
249
- overrides["org_id"] = org_id
250
- if project_id is not None:
251
- overrides["project_id"] = project_id
252
- if base_url is not None:
253
- overrides["base_url"] = base_url
254
- if default_model is not None:
255
- overrides["default_model"] = default_model
256
- if parsed_timeout is not None:
257
- overrides["timeout"] = parsed_timeout
258
- if parsed_max_retries is not None:
259
- overrides["max_retries"] = parsed_max_retries
260
- if extra_kwargs:
261
- overrides["extra_client_kwargs"] = extra_kwargs
262
-
263
- try:
264
- return OpenAISettings.from_env(dotenv_path=dotenv_path, **overrides)
265
- except ValueError as exc:
266
- # Re-raise with more context but preserve original message
267
- raise ValueError(f"Failed to build OpenAI settings: {exc}") from exc
268
-
269
-
270
- T = TypeVar("T")
271
- _configured_logging = False
272
-
273
-
274
- def ensure_list(value: Iterable[T] | T | None) -> list[T]:
275
- """Normalize a single item or iterable into a list.
276
-
277
- Converts None to empty list, tuples to lists, and wraps single
278
- items in a list.
279
-
280
- Parameters
281
- ----------
282
- value : Iterable[T] | T | None
283
- Item or iterable to wrap. None yields an empty list.
284
-
285
- Returns
286
- -------
287
- list[T]
288
- Normalized list representation of value.
289
-
290
- Examples
291
- --------
292
- >>> ensure_list(None)
293
- []
294
- >>> ensure_list(5)
295
- [5]
296
- >>> ensure_list([1, 2, 3])
297
- [1, 2, 3]
298
- >>> ensure_list(("a", "b"))
299
- ['a', 'b']
300
- """
301
- if value is None:
302
- return []
303
- if isinstance(value, list):
304
- return value
305
- if isinstance(value, tuple):
306
- return list(value)
307
- return [value] # type: ignore[list-item]
308
-
309
-
310
- def check_filepath(
311
- filepath: Path | None = None, *, fullfilepath: str | None = None
312
- ) -> Path:
313
- """Ensure the parent directory for a file path exists.
314
-
315
- Creates parent directories as needed. Exactly one of filepath or
316
- fullfilepath must be provided.
317
-
318
- Parameters
319
- ----------
320
- filepath : Path or None, optional
321
- Path object to validate. Mutually exclusive with fullfilepath.
322
- fullfilepath : str or None, optional
323
- String path to validate. Mutually exclusive with filepath.
324
-
325
- Returns
326
- -------
327
- Path
328
- Path object representing the validated file path.
329
-
330
- Raises
331
- ------
332
- ValueError
333
- If neither filepath nor fullfilepath is provided.
334
-
335
- Examples
336
- --------
337
- >>> from pathlib import Path
338
- >>> path = check_filepath(filepath=Path("/tmp/test.txt"))
339
- >>> isinstance(path, Path)
340
- True
341
- """
342
- if filepath is None and fullfilepath is None:
343
- raise ValueError("filepath or fullfilepath is required.")
344
- if fullfilepath is not None:
345
- target = Path(fullfilepath)
346
- elif filepath is not None:
347
- target = Path(filepath)
348
- else:
349
- raise ValueError("filepath or fullfilepath is required.")
350
- target.parent.mkdir(parents=True, exist_ok=True)
351
- return target
352
-
353
-
354
- def _to_jsonable(value: Any) -> Any:
355
- """Convert common helper types to JSON-serializable forms.
356
-
357
- Handles Enum, Path, datetime, dataclasses, Pydantic models, dicts,
358
- lists, tuples, and sets.
359
-
360
- Parameters
361
- ----------
362
- value : Any
363
- Value to convert.
364
-
365
- Returns
366
- -------
367
- Any
368
- A JSON-safe representation of value.
369
-
370
- Notes
371
- -----
372
- This is an internal helper function. Use coerce_jsonable for public API.
373
- """
374
- if value is None:
375
- return None
376
- if isinstance(value, Enum):
377
- return value.value
378
- if isinstance(value, Path):
379
- return str(value)
380
- if isinstance(value, datetime):
381
- return value.isoformat()
382
- if is_dataclass(value) and not isinstance(value, type):
383
- return {k: _to_jsonable(v) for k, v in asdict(value).items()}
384
- if hasattr(value, "model_dump"):
385
- model_dump = getattr(value, "model_dump")
386
- return model_dump()
387
- if isinstance(value, dict):
388
- return {str(k): _to_jsonable(v) for k, v in value.items()}
389
- if isinstance(value, (list, tuple, set)):
390
- return [_to_jsonable(v) for v in value]
391
- return value
392
-
393
-
394
- def coerce_jsonable(value: Any) -> Any:
395
- """Convert value into a JSON-serializable representation.
396
-
397
- Handles BaseStructure, BaseResponse, dataclasses, and other complex
398
- types by recursively converting them to JSON-compatible forms.
399
-
400
- Parameters
401
- ----------
402
- value : Any
403
- Object to convert into a JSON-friendly structure.
404
-
405
- Returns
406
- -------
407
- Any
408
- JSON-serializable representation of value.
409
-
410
- Examples
411
- --------
412
- >>> from datetime import datetime
413
- >>> result = coerce_jsonable({"date": datetime(2024, 1, 1)})
414
- >>> isinstance(result, dict)
415
- True
416
- """
417
- from openai_sdk_helpers.response.base import BaseResponse
418
- from openai_sdk_helpers.structure.base import BaseStructure
419
-
420
- if value is None:
421
- return None
422
- if isinstance(value, BaseStructure):
423
- return value.model_dump()
424
- if isinstance(value, BaseResponse):
425
- return coerce_jsonable(value.messages.to_json())
426
- if is_dataclass(value) and not isinstance(value, type):
427
- return {key: coerce_jsonable(item) for key, item in asdict(value).items()}
428
- coerced = _to_jsonable(value)
429
- try:
430
- json.dumps(coerced)
431
- return coerced
432
- except TypeError:
433
- return str(coerced)
434
-
435
-
436
- class customJSONEncoder(json.JSONEncoder):
437
- """JSON encoder for common helper types like enums and paths.
438
-
439
- Extends json.JSONEncoder to handle Enum, Path, datetime, dataclasses,
440
- and Pydantic models automatically.
441
-
442
- Methods
443
- -------
444
- default(o)
445
- Return a JSON-serializable representation of o.
446
-
447
- Examples
448
- --------
449
- >>> import json
450
- >>> from pathlib import Path
451
- >>> json.dumps({"path": Path("/tmp")}, cls=customJSONEncoder)
452
- '{"path": "/tmp"}'
453
- """
454
-
455
- def default(self, o: Any) -> Any:
456
- """Return a JSON-serializable representation of o.
457
-
458
- Called by the json module when the default serialization fails.
459
- Delegates to _to_jsonable for type-specific conversions.
460
-
461
- Parameters
462
- ----------
463
- o : Any
464
- Object to serialize.
465
-
466
- Returns
467
- -------
468
- Any
469
- JSON-safe representation of o.
470
- """
471
- return _to_jsonable(o)
472
-
473
-
474
- class JSONSerializable:
475
- """Mixin for classes that can be serialized to JSON.
476
-
477
- Provides to_json() and to_json_file() methods for any class. Works
478
- with dataclasses, Pydantic models, and regular classes with __dict__.
479
-
480
- Methods
481
- -------
482
- to_json()
483
- Return a JSON-compatible dict representation of the instance.
484
- to_json_file(filepath)
485
- Write serialized JSON data to a file path.
486
-
487
- Examples
488
- --------
489
- >>> from dataclasses import dataclass
490
- >>> @dataclass
491
- ... class MyClass(JSONSerializable):
492
- ... value: int
493
- >>> obj = MyClass(value=42)
494
- >>> obj.to_json()
495
- {'value': 42}
496
- """
497
-
498
- def to_json(self) -> dict[str, Any]:
499
- """Return a JSON-compatible dict representation.
500
-
501
- Automatically handles dataclasses, Pydantic models, and objects
502
- with __dict__ attributes.
503
-
504
- Returns
505
- -------
506
- dict[str, Any]
507
- Mapping with only JSON-serializable values.
508
-
509
- Examples
510
- --------
511
- >>> obj = JSONSerializable()
512
- >>> result = obj.to_json()
513
- >>> isinstance(result, dict)
514
- True
515
- """
516
- if is_dataclass(self) and not isinstance(self, type):
517
- return {k: _to_jsonable(v) for k, v in asdict(self).items()}
518
- if hasattr(self, "model_dump"):
519
- model_dump = getattr(self, "model_dump")
520
- return _to_jsonable(model_dump())
521
- return _to_jsonable(self.__dict__)
522
-
523
- def to_json_file(self, filepath: str | Path) -> str:
524
- """Write serialized JSON data to a file path.
525
-
526
- Creates parent directories as needed. Uses customJSONEncoder for
527
- handling special types.
528
-
529
- Parameters
530
- ----------
531
- filepath : str | Path
532
- Destination file path. Parent directories are created as needed.
533
-
534
- Returns
535
- -------
536
- str
537
- String representation of the file path written.
538
-
539
- Examples
540
- --------
541
- >>> obj = JSONSerializable()
542
- >>> path = obj.to_json_file("/tmp/output.json") # doctest: +SKIP
543
- """
544
- target = Path(filepath)
545
- check_filepath(fullfilepath=str(target))
546
- with open(target, "w", encoding="utf-8") as handle:
547
- json.dump(
548
- self.to_json(),
549
- handle,
550
- indent=2,
551
- ensure_ascii=False,
552
- cls=customJSONEncoder,
553
- )
554
- return str(target)
555
-
556
-
557
- def log(message: str, level: int = logging.INFO) -> None:
558
- """Log a message with a basic configuration.
559
-
560
- Configures logging on first use with a simple timestamp format.
561
- Subsequent calls use the existing configuration.
562
-
563
- Parameters
564
- ----------
565
- message : str
566
- Message to emit.
567
- level : int, optional
568
- Logging level (e.g., logging.INFO, logging.WARNING), by default
569
- logging.INFO.
570
-
571
- Examples
572
- --------
573
- >>> import logging
574
- >>> log("Test message", level=logging.INFO) # doctest: +SKIP
575
- """
576
- global _configured_logging
577
- if not _configured_logging:
578
- logging.basicConfig(
579
- level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s"
580
- )
581
- _configured_logging = True
582
- logging.log(level, message)
583
-
584
-
585
- __all__ = [
586
- "ensure_list",
587
- "check_filepath",
588
- "coerce_jsonable",
589
- "JSONSerializable",
590
- "customJSONEncoder",
591
- "log",
592
- "coerce_optional_float",
593
- "coerce_optional_int",
594
- "coerce_dict",
595
- "build_openai_settings",
596
- ]
@@ -1,69 +0,0 @@
1
- openai_sdk_helpers/__init__.py,sha256=yFWF1rBF8-mCVPK-_PfiCaBMIVl_NGvJb4wySXWenhg,3765
2
- openai_sdk_helpers/async_utils.py,sha256=_GPiSDQhWehiZu2S_jB_Xgl0p2qGc5MNu1NN92zz3bg,3726
3
- openai_sdk_helpers/config.py,sha256=841YGiUu7hvFrB2Bdr6ck4YKCtb2HRI0Uhk6HKpIqAc,7640
4
- openai_sdk_helpers/context_manager.py,sha256=9z54rjcJ-nAFdEoZHjFdk1YYpeD9bet13MOgn23FzM8,6629
5
- openai_sdk_helpers/environment.py,sha256=HSPI1h1JUuMxzcTSvr28ktHBvyEJLRzL4bZhNfy59lI,1372
6
- openai_sdk_helpers/errors.py,sha256=oytqn-6Jg6nPMQOP956ftfkLS0R5c1XBDX-lNstrb3Y,3135
7
- openai_sdk_helpers/logging_config.py,sha256=fOKBgisOkM0VYDt68pmUSxVWzTeO25_u-El0HOxqEYM,2928
8
- openai_sdk_helpers/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- openai_sdk_helpers/retry.py,sha256=3I5cZOq5X6d7kno3fk1SVDYJ7U2VDHqBS7ZsaXWbU6A,6529
10
- openai_sdk_helpers/tools.py,sha256=MW6bdJH9Ij16LKNCNNvSthq206T-orTOQTLFzLWxQTo,6043
11
- openai_sdk_helpers/types.py,sha256=xzldCRfwCZ3rZl18IBmfgA-PVdoZKSWNrlSIhirumSo,1451
12
- openai_sdk_helpers/validation.py,sha256=fr3zVZ7uEokJJqF3LSIcQm4wV3MvWXcep2ZRpseXZBk,7789
13
- openai_sdk_helpers/agent/__init__.py,sha256=giowU8jke0z0h7FFUG9V6Vssja8AYwvJMQbiMb3s64k,960
14
- openai_sdk_helpers/agent/base.py,sha256=CKHfcUsBc8Hd5UAKehHw6E3GVEs7VasZZ0M8WrWJPv4,11737
15
- openai_sdk_helpers/agent/config.py,sha256=htqy5bcrJeMf3rIpRdL9CKlYwyQI4po420rcgR3i8XI,1971
16
- openai_sdk_helpers/agent/coordination.py,sha256=00iJPHZvpLEDRDeon_HRQPEHdyQnEk4NTjAj9VgkqVI,16204
17
- openai_sdk_helpers/agent/prompt_utils.py,sha256=-1M66tqQxh9wWCFg6X-K7cCcqauca3yA04ZjvOpN3bA,337
18
- openai_sdk_helpers/agent/runner.py,sha256=XRa17OV8f0G8--6qyUFw6BwJSHBNe_Yx8DFajxVYFxA,4137
19
- openai_sdk_helpers/agent/summarizer.py,sha256=fH8AnYK_68ERf2U7mv0nwXL8KyhrluE-TDY_M5TCdD0,3266
20
- openai_sdk_helpers/agent/translator.py,sha256=GhUuwFTBecgOO9pMQ41VPvK9mTub5DXJ_7BIS9Xp7bs,5082
21
- openai_sdk_helpers/agent/utils.py,sha256=DTD5foCqGYfXf13F2bZMYIQROl7SbDSy5GDPGi0Zl-0,1089
22
- openai_sdk_helpers/agent/validation.py,sha256=JIYVhBTTs0tTxYyzYgY3BHC-9psyzE3LLQDZDqpg13M,4191
23
- openai_sdk_helpers/agent/search/__init__.py,sha256=xqosfzH4HcBs9IFZks9msG_694rS5q6Ea4_qNeRQRmU,798
24
- openai_sdk_helpers/agent/search/base.py,sha256=05ERHgNqUrG7bs0zrtFgDps_m_dq1b_Hr1W1aSWm5BM,8602
25
- openai_sdk_helpers/agent/search/vector.py,sha256=ebIRPFusLJa5SfwV4Ush_8eoLVMlH0OsOFi_dCFXF0M,13600
26
- openai_sdk_helpers/agent/search/web.py,sha256=8le4xnZ3nllySqWb7rZaOq44ZR8q67c_WiE57ncmL90,10014
27
- openai_sdk_helpers/enums/__init__.py,sha256=aFf79C4JBeLC3kMlJfSpehyjx5uNCtW6eK5rD6ZFfhM,322
28
- openai_sdk_helpers/enums/base.py,sha256=cNllDtzcgI0_eZYXxFko14yhxwicX6xbeDfz9gFE3qo,2753
29
- openai_sdk_helpers/prompt/__init__.py,sha256=MOqgKwG9KLqKudoKRlUfLxiSmdOi2aD6hNrWDFqLHkk,418
30
- openai_sdk_helpers/prompt/base.py,sha256=FvQNEjIdYDLvGEiR9_dbEn6G47TPMsWm4r26jcLjgus,7569
31
- openai_sdk_helpers/prompt/summarizer.jinja,sha256=jliSetWDISbql1EkWi1RB8-L_BXUg8JMkRRsPRHuzbY,309
32
- openai_sdk_helpers/prompt/translator.jinja,sha256=SZhW8ipEzM-9IA4wyS_r2wIMTAclWrilmk1s46njoL0,291
33
- openai_sdk_helpers/prompt/validator.jinja,sha256=6t8q_IdxFd3mVBGX6SFKNOert1Wo3YpTOji2SNEbbtE,547
34
- openai_sdk_helpers/response/__init__.py,sha256=eoQF086o3OZYmVfJWXhSpYlPhQBb-VLDA5hvw7guLEc,1741
35
- openai_sdk_helpers/response/base.py,sha256=-d-vvY4OId_MU6EAN55bBPEftnskw9Ry8TVQ705f9Xw,27965
36
- openai_sdk_helpers/response/config.py,sha256=WheEWkTxNFHL54_yvFY3M0LclNmajwTiMftSFeAH2eI,10300
37
- openai_sdk_helpers/response/messages.py,sha256=oVSHpSV_iQxHreCXm--a6MlHg_kkElQi3R2Y8Y7VphA,9134
38
- openai_sdk_helpers/response/runner.py,sha256=Rf13cQGsR7sN9gA81Y5th1tfH2DCCAwQ6RMs3bVgjnk,4269
39
- openai_sdk_helpers/response/tool_call.py,sha256=VYPvKUR-Ren0Y_nYS4jUSinhTyXKzFwQLxu-d3r_YuM,4506
40
- openai_sdk_helpers/response/vector_store.py,sha256=MyHUu6P9ueNsd9erbBkyVqq3stLK6qVuehdvmFAHq9E,3074
41
- openai_sdk_helpers/streamlit_app/__init__.py,sha256=RjJbnBDS5_YmAmxvaa3phB5u9UcXsXDEk_jMlY_pa5Q,793
42
- openai_sdk_helpers/streamlit_app/app.py,sha256=ID3B4fUQHvv1Cwuuvrlm4nK4d0nWL6uBE40O_T6r7yY,10808
43
- openai_sdk_helpers/streamlit_app/config.py,sha256=EK6LWACo7YIkDko1oesvupOx56cTuWWnwnXRiu8EYbs,15986
44
- openai_sdk_helpers/streamlit_app/streamlit_web_search.py,sha256=OrX-kgW_yaHgIsK6wY9gBVLbvDaMFXgkgdhKQDsA8kQ,2506
45
- openai_sdk_helpers/structure/__init__.py,sha256=QUvRdJMbKsumjwJdWq9ihfcOED4ZbJMBQbmA1nmYJVw,3339
46
- openai_sdk_helpers/structure/agent_blueprint.py,sha256=2W-RBM5G3ZefMcYHqqoV6Y1witcSbMlUpdU1CA9n3tg,9698
47
- openai_sdk_helpers/structure/base.py,sha256=7RMsCMjQR7u3mksirqd0E6AgCgWEMVRQtgNefwHWPGo,28278
48
- openai_sdk_helpers/structure/prompt.py,sha256=7DBdLu6WDvXy2RkEBayDiX2Jn8T4-hJuohsOaKEoqJs,1075
49
- openai_sdk_helpers/structure/responses.py,sha256=iYJBT_4VFifzQqPnTpRWTcB0o7xkhPIQ2ugedivrpto,4868
50
- openai_sdk_helpers/structure/summary.py,sha256=MyZzMuqHP9F8B4rYYxCGJwojy5RavWUkMiRZ6yMQzvU,3143
51
- openai_sdk_helpers/structure/validation.py,sha256=vsilA3Qs3fjWLeYlnZnMEGj9i_bOJtXc2J3mSIEHncg,2409
52
- openai_sdk_helpers/structure/vector_search.py,sha256=A0w2AR0r6aIFoYbNkscUAGT7VzTe6WuvxrqUsWT2PMQ,5782
53
- openai_sdk_helpers/structure/web_search.py,sha256=S8OdllBWqEGXaKf6Alocl89ZuG7BlvXK5ra1Lm7lfjE,4572
54
- openai_sdk_helpers/structure/plan/__init__.py,sha256=IGr0Tk4inN_8o7fT2N02_FTi6U6l2T9_npcQHAlBwKA,1076
55
- openai_sdk_helpers/structure/plan/enum.py,sha256=seESSwH-IeeW-9BqIMUQyk3qjtchfU3TDhF9HPDB1OM,3079
56
- openai_sdk_helpers/structure/plan/helpers.py,sha256=25qXUMPY73y3E6EsE88n9VBwNj2JZkzXy1AaWGsoSLw,5132
57
- openai_sdk_helpers/structure/plan/plan.py,sha256=LtfwWwZiHGe06nFCXSbT8p3x3w9hhI0wXS7hTeeWXvY,9663
58
- openai_sdk_helpers/structure/plan/task.py,sha256=2dH8iaLhjC7MKZEW1T_HICaggi1RPyKSPOl9ORmmYdg,4538
59
- openai_sdk_helpers/structure/plan/types.py,sha256=7y9QEVdZreQUXV7n-R4RoNZzw5HeOVbJGWx9QkSfuNY,418
60
- openai_sdk_helpers/utils/__init__.py,sha256=oNMc8xyOGmXLNIOjwC5EhN8Jjy_S74Vgwzzg41RNb4g,1566
61
- openai_sdk_helpers/utils/core.py,sha256=Ehm9WePZTl9ypbbKlHNiyRkhI4a5ZhbDwKiSJTNTgz8,17262
62
- openai_sdk_helpers/vector_storage/__init__.py,sha256=L5LxO09puh9_yBB9IDTvc1CvVkARVkHqYY1KX3inB4c,975
63
- openai_sdk_helpers/vector_storage/cleanup.py,sha256=ImWIE-9lli-odD8qIARvmeaa0y8ZD4pYYP-kT0O3178,3552
64
- openai_sdk_helpers/vector_storage/storage.py,sha256=ZiTZnvCY28R-WUQjHdnjQo1xIRbXAM6JL0VhqW9MM9I,21725
65
- openai_sdk_helpers/vector_storage/types.py,sha256=jTCcOYMeOpZWvcse0z4T3MVs-RBOPC-fqWTBeQrgafU,1639
66
- openai_sdk_helpers-0.1.0.dist-info/METADATA,sha256=R-Lc44fSOhAohVtwOAVW_pg3_GMHfYW5ve3bwZlIETE,18492
67
- openai_sdk_helpers-0.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
68
- openai_sdk_helpers-0.1.0.dist-info/licenses/LICENSE,sha256=CUhc1NrE50bs45tcXF7OcTQBKEvkUuLqeOHgrWQ5jaA,1067
69
- openai_sdk_helpers-0.1.0.dist-info/RECORD,,