openaivec 0.13.5__tar.gz → 0.13.6__tar.gz

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 (84) hide show
  1. {openaivec-0.13.5 → openaivec-0.13.6}/.github/workflows/python-test.yml +3 -0
  2. {openaivec-0.13.5 → openaivec-0.13.6}/PKG-INFO +9 -9
  3. {openaivec-0.13.5 → openaivec-0.13.6}/README.md +8 -8
  4. {openaivec-0.13.5 → openaivec-0.13.6}/pyproject.toml +1 -0
  5. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/embeddings.py +10 -8
  6. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/model.py +9 -11
  7. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/optimize.py +1 -1
  8. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/pandas_ext.py +61 -42
  9. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/prompt.py +58 -8
  10. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/provider.py +10 -0
  11. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/proxy.py +82 -65
  12. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/responses.py +35 -18
  13. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/spark.py +40 -34
  14. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/task/customer_support/inquiry_classification.py +9 -9
  15. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/task/customer_support/urgency_analysis.py +13 -13
  16. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/task/nlp/keyword_extraction.py +2 -2
  17. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/task/nlp/named_entity_recognition.py +2 -2
  18. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/util.py +2 -2
  19. {openaivec-0.13.5 → openaivec-0.13.6}/tests/test_optimize.py +1 -1
  20. {openaivec-0.13.5 → openaivec-0.13.6}/tests/test_provider.py +28 -28
  21. {openaivec-0.13.5 → openaivec-0.13.6}/tests/test_proxy.py +9 -9
  22. {openaivec-0.13.5 → openaivec-0.13.6}/uv.lock +24 -0
  23. {openaivec-0.13.5 → openaivec-0.13.6}/.env.example +0 -0
  24. {openaivec-0.13.5 → openaivec-0.13.6}/.github/copilot-instructions.md +0 -0
  25. {openaivec-0.13.5 → openaivec-0.13.6}/.github/workflows/python-mkdocs.yml +0 -0
  26. {openaivec-0.13.5 → openaivec-0.13.6}/.github/workflows/python-package.yml +0 -0
  27. {openaivec-0.13.5 → openaivec-0.13.6}/.github/workflows/python-update.yml +0 -0
  28. {openaivec-0.13.5 → openaivec-0.13.6}/.gitignore +0 -0
  29. {openaivec-0.13.5 → openaivec-0.13.6}/CODE_OF_CONDUCT.md +0 -0
  30. {openaivec-0.13.5 → openaivec-0.13.6}/LICENSE +0 -0
  31. {openaivec-0.13.5 → openaivec-0.13.6}/SECURITY.md +0 -0
  32. {openaivec-0.13.5 → openaivec-0.13.6}/SUPPORT.md +0 -0
  33. {openaivec-0.13.5 → openaivec-0.13.6}/docs/api/di.md +0 -0
  34. {openaivec-0.13.5 → openaivec-0.13.6}/docs/api/embeddings.md +0 -0
  35. {openaivec-0.13.5 → openaivec-0.13.6}/docs/api/pandas_ext.md +0 -0
  36. {openaivec-0.13.5 → openaivec-0.13.6}/docs/api/prompt.md +0 -0
  37. {openaivec-0.13.5 → openaivec-0.13.6}/docs/api/proxy.md +0 -0
  38. {openaivec-0.13.5 → openaivec-0.13.6}/docs/api/responses.md +0 -0
  39. {openaivec-0.13.5 → openaivec-0.13.6}/docs/api/spark.md +0 -0
  40. {openaivec-0.13.5 → openaivec-0.13.6}/docs/api/task.md +0 -0
  41. {openaivec-0.13.5 → openaivec-0.13.6}/docs/api/tasks/customer_support/customer_sentiment.md +0 -0
  42. {openaivec-0.13.5 → openaivec-0.13.6}/docs/api/tasks/customer_support/inquiry_classification.md +0 -0
  43. {openaivec-0.13.5 → openaivec-0.13.6}/docs/api/tasks/customer_support/inquiry_summary.md +0 -0
  44. {openaivec-0.13.5 → openaivec-0.13.6}/docs/api/tasks/customer_support/intent_analysis.md +0 -0
  45. {openaivec-0.13.5 → openaivec-0.13.6}/docs/api/tasks/customer_support/response_suggestion.md +0 -0
  46. {openaivec-0.13.5 → openaivec-0.13.6}/docs/api/tasks/customer_support/urgency_analysis.md +0 -0
  47. {openaivec-0.13.5 → openaivec-0.13.6}/docs/api/tasks/nlp/dependency_parsing.md +0 -0
  48. {openaivec-0.13.5 → openaivec-0.13.6}/docs/api/tasks/nlp/keyword_extraction.md +0 -0
  49. {openaivec-0.13.5 → openaivec-0.13.6}/docs/api/tasks/nlp/morphological_analysis.md +0 -0
  50. {openaivec-0.13.5 → openaivec-0.13.6}/docs/api/tasks/nlp/named_entity_recognition.md +0 -0
  51. {openaivec-0.13.5 → openaivec-0.13.6}/docs/api/tasks/nlp/sentiment_analysis.md +0 -0
  52. {openaivec-0.13.5 → openaivec-0.13.6}/docs/api/tasks/nlp/translation.md +0 -0
  53. {openaivec-0.13.5 → openaivec-0.13.6}/docs/api/util.md +0 -0
  54. {openaivec-0.13.5 → openaivec-0.13.6}/docs/index.md +0 -0
  55. {openaivec-0.13.5 → openaivec-0.13.6}/docs/robots.txt +0 -0
  56. {openaivec-0.13.5 → openaivec-0.13.6}/mkdocs.yml +0 -0
  57. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/__init__.py +0 -0
  58. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/di.py +0 -0
  59. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/log.py +0 -0
  60. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/serialize.py +0 -0
  61. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/task/__init__.py +0 -0
  62. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/task/customer_support/__init__.py +0 -0
  63. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/task/customer_support/customer_sentiment.py +0 -0
  64. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/task/customer_support/inquiry_summary.py +0 -0
  65. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/task/customer_support/intent_analysis.py +0 -0
  66. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/task/customer_support/response_suggestion.py +0 -0
  67. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/task/nlp/__init__.py +0 -0
  68. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/task/nlp/dependency_parsing.py +0 -0
  69. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/task/nlp/morphological_analysis.py +0 -0
  70. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/task/nlp/sentiment_analysis.py +0 -0
  71. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/task/nlp/translation.py +0 -0
  72. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/task/table/__init__.py +0 -0
  73. {openaivec-0.13.5 → openaivec-0.13.6}/src/openaivec/task/table/fillna.py +0 -0
  74. {openaivec-0.13.5 → openaivec-0.13.6}/tests/__init__.py +0 -0
  75. {openaivec-0.13.5 → openaivec-0.13.6}/tests/test_di.py +0 -0
  76. {openaivec-0.13.5 → openaivec-0.13.6}/tests/test_embeddings.py +0 -0
  77. {openaivec-0.13.5 → openaivec-0.13.6}/tests/test_pandas_ext.py +0 -0
  78. {openaivec-0.13.5 → openaivec-0.13.6}/tests/test_prompt.py +0 -0
  79. {openaivec-0.13.5 → openaivec-0.13.6}/tests/test_proxy_suggester.py +0 -0
  80. {openaivec-0.13.5 → openaivec-0.13.6}/tests/test_responses.py +0 -0
  81. {openaivec-0.13.5 → openaivec-0.13.6}/tests/test_serialize.py +0 -0
  82. {openaivec-0.13.5 → openaivec-0.13.6}/tests/test_spark.py +0 -0
  83. {openaivec-0.13.5 → openaivec-0.13.6}/tests/test_task.py +0 -0
  84. {openaivec-0.13.5 → openaivec-0.13.6}/tests/test_util.py +0 -0
@@ -27,5 +27,8 @@ jobs:
27
27
  - name: Lint with ruff
28
28
  run: uv run ruff check .
29
29
 
30
+ - name: Type check with pyright
31
+ run: uv run pyright src/openaivec || echo "Type check completed with issues - see above"
32
+
30
33
  - name: Run tests
31
34
  run: uv run pytest
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openaivec
3
- Version: 0.13.5
3
+ Version: 0.13.6
4
4
  Summary: Generative mutation for tabular calculation
5
5
  Project-URL: Homepage, https://microsoft.github.io/openaivec/
6
6
  Project-URL: Repository, https://github.com/microsoft/openaivec
@@ -159,7 +159,7 @@ client = BatchResponses.of(
159
159
  client=OpenAI(),
160
160
  model_name="gpt-4.1-mini",
161
161
  system_message="Please answer only with 'xx family' and do not output anything else.",
162
- batch_size=32,
162
+ # batch_size defaults to None (automatic optimization)
163
163
  )
164
164
 
165
165
  result = client.parse(["panda", "rabbit", "koala"])
@@ -304,7 +304,7 @@ async def process_data():
304
304
  # Asynchronous processing with fine-tuned concurrency control
305
305
  results = await df["text"].aio.responses(
306
306
  "Analyze sentiment and classify as positive/negative/neutral",
307
- batch_size=64, # Process 64 items per API request
307
+ # batch_size defaults to None (automatic optimization)
308
308
  max_concurrency=12 # Allow up to 12 concurrent requests
309
309
  )
310
310
  return results
@@ -315,7 +315,7 @@ sentiments = asyncio.run(process_data())
315
315
 
316
316
  **Key Parameters for Performance Tuning:**
317
317
 
318
- - **`batch_size`** (default: 128): Controls how many inputs are grouped into a single API request. Higher values reduce API call overhead but increase memory usage and request processing time.
318
+ - **`batch_size`** (default: None): Controls how many inputs are grouped into a single API request. When None (default), automatic batch size optimization adjusts based on execution time. Set to a positive integer for fixed batch size. Higher values reduce API call overhead but increase memory usage and request processing time.
319
319
  - **`max_concurrency`** (default: 8): Limits the number of concurrent API requests. Higher values increase throughput but may hit rate limits or overwhelm the API.
320
320
 
321
321
  **Performance Benefits:**
@@ -460,12 +460,12 @@ When using openaivec with Spark, proper configuration of `batch_size` and `max_c
460
460
  - **Transparent**: Works automatically without code changes - your existing UDFs become more efficient
461
461
  - **Partition-Level**: Each partition maintains its own cache, optimal for distributed processing patterns
462
462
 
463
- **`batch_size`** (default: 128):
463
+ **`batch_size`** (default: None):
464
464
 
465
465
  - Controls how many rows are processed together in each API request within a partition
466
- - **Larger values**: Fewer API calls per partition, reduced overhead
467
- - **Smaller values**: More granular processing, better memory management
468
- - **Recommendation**: 32-128 depending on data complexity and partition size
466
+ - **Default (None)**: Automatic batch size optimization adjusts based on execution time
467
+ - **Positive integer**: Fixed batch size - larger values reduce API calls but increase memory usage
468
+ - **Recommendation**: Use default automatic optimization, or set 32-128 for fixed batch size
469
469
 
470
470
  **`max_concurrency`** (default: 8):
471
471
 
@@ -483,7 +483,7 @@ spark.udf.register(
483
483
  "analyze_sentiment",
484
484
  responses_udf(
485
485
  instructions="Analyze sentiment as positive/negative/neutral",
486
- batch_size=64, # Good balance for most use cases
486
+ # batch_size defaults to None (automatic optimization)
487
487
  max_concurrency=8 # 80 total concurrent requests across cluster
488
488
  )
489
489
  )
@@ -133,7 +133,7 @@ client = BatchResponses.of(
133
133
  client=OpenAI(),
134
134
  model_name="gpt-4.1-mini",
135
135
  system_message="Please answer only with 'xx family' and do not output anything else.",
136
- batch_size=32,
136
+ # batch_size defaults to None (automatic optimization)
137
137
  )
138
138
 
139
139
  result = client.parse(["panda", "rabbit", "koala"])
@@ -278,7 +278,7 @@ async def process_data():
278
278
  # Asynchronous processing with fine-tuned concurrency control
279
279
  results = await df["text"].aio.responses(
280
280
  "Analyze sentiment and classify as positive/negative/neutral",
281
- batch_size=64, # Process 64 items per API request
281
+ # batch_size defaults to None (automatic optimization)
282
282
  max_concurrency=12 # Allow up to 12 concurrent requests
283
283
  )
284
284
  return results
@@ -289,7 +289,7 @@ sentiments = asyncio.run(process_data())
289
289
 
290
290
  **Key Parameters for Performance Tuning:**
291
291
 
292
- - **`batch_size`** (default: 128): Controls how many inputs are grouped into a single API request. Higher values reduce API call overhead but increase memory usage and request processing time.
292
+ - **`batch_size`** (default: None): Controls how many inputs are grouped into a single API request. When None (default), automatic batch size optimization adjusts based on execution time. Set to a positive integer for fixed batch size. Higher values reduce API call overhead but increase memory usage and request processing time.
293
293
  - **`max_concurrency`** (default: 8): Limits the number of concurrent API requests. Higher values increase throughput but may hit rate limits or overwhelm the API.
294
294
 
295
295
  **Performance Benefits:**
@@ -434,12 +434,12 @@ When using openaivec with Spark, proper configuration of `batch_size` and `max_c
434
434
  - **Transparent**: Works automatically without code changes - your existing UDFs become more efficient
435
435
  - **Partition-Level**: Each partition maintains its own cache, optimal for distributed processing patterns
436
436
 
437
- **`batch_size`** (default: 128):
437
+ **`batch_size`** (default: None):
438
438
 
439
439
  - Controls how many rows are processed together in each API request within a partition
440
- - **Larger values**: Fewer API calls per partition, reduced overhead
441
- - **Smaller values**: More granular processing, better memory management
442
- - **Recommendation**: 32-128 depending on data complexity and partition size
440
+ - **Default (None)**: Automatic batch size optimization adjusts based on execution time
441
+ - **Positive integer**: Fixed batch size - larger values reduce API calls but increase memory usage
442
+ - **Recommendation**: Use default automatic optimization, or set 32-128 for fixed batch size
443
443
 
444
444
  **`max_concurrency`** (default: 8):
445
445
 
@@ -457,7 +457,7 @@ spark.udf.register(
457
457
  "analyze_sentiment",
458
458
  responses_udf(
459
459
  instructions="Analyze sentiment as positive/negative/neutral",
460
- batch_size=64, # Good balance for most use cases
460
+ # batch_size defaults to None (automatic optimization)
461
461
  max_concurrency=8 # 80 total concurrent requests across cluster
462
462
  )
463
463
  )
@@ -39,6 +39,7 @@ dev = [
39
39
  "ipykernel>=6.29.5",
40
40
  "langdetect>=1.0.9",
41
41
  "pyarrow>=19.0.1",
42
+ "pyright>=1.1.403",
42
43
  "pyspark>=3.5.5",
43
44
  "pytest>=8.3.5",
44
45
  "pytest-asyncio",
@@ -31,16 +31,17 @@ class BatchEmbeddings:
31
31
 
32
32
  client: OpenAI
33
33
  model_name: str
34
- cache: BatchingMapProxy[str, NDArray[np.float32]] = field(default_factory=lambda: BatchingMapProxy(batch_size=128))
34
+ cache: BatchingMapProxy[str, NDArray[np.float32]] = field(default_factory=lambda: BatchingMapProxy(batch_size=None))
35
35
 
36
36
  @classmethod
37
- def of(cls, client: OpenAI, model_name: str, batch_size: int = 128) -> "BatchEmbeddings":
37
+ def of(cls, client: OpenAI, model_name: str, batch_size: int | None = None) -> "BatchEmbeddings":
38
38
  """Factory constructor.
39
39
 
40
40
  Args:
41
41
  client (OpenAI): OpenAI client.
42
42
  model_name (str): For Azure OpenAI, use your deployment name. For OpenAI, use the model name.
43
- batch_size (int, optional): Max unique inputs per API call. Defaults to 128.
43
+ batch_size (int | None, optional): Max unique inputs per API call. Defaults to None
44
+ (automatic batch size optimization). Set to a positive integer for fixed batch size.
44
45
 
45
46
  Returns:
46
47
  BatchEmbeddings: Configured instance backed by a batching proxy.
@@ -127,7 +128,7 @@ class AsyncBatchEmbeddings:
127
128
  client: AsyncOpenAI
128
129
  model_name: str
129
130
  cache: AsyncBatchingMapProxy[str, NDArray[np.float32]] = field(
130
- default_factory=lambda: AsyncBatchingMapProxy(batch_size=128, max_concurrency=8)
131
+ default_factory=lambda: AsyncBatchingMapProxy(batch_size=None, max_concurrency=8)
131
132
  )
132
133
 
133
134
  @classmethod
@@ -135,7 +136,7 @@ class AsyncBatchEmbeddings:
135
136
  cls,
136
137
  client: AsyncOpenAI,
137
138
  model_name: str,
138
- batch_size: int = 128,
139
+ batch_size: int | None = None,
139
140
  max_concurrency: int = 8,
140
141
  ) -> "AsyncBatchEmbeddings":
141
142
  """Factory constructor.
@@ -143,7 +144,8 @@ class AsyncBatchEmbeddings:
143
144
  Args:
144
145
  client (AsyncOpenAI): OpenAI async client.
145
146
  model_name (str): For Azure OpenAI, use your deployment name. For OpenAI, use the model name.
146
- batch_size (int, optional): Max unique inputs per API call. Defaults to 128.
147
+ batch_size (int | None, optional): Max unique inputs per API call. Defaults to None
148
+ (automatic batch size optimization). Set to a positive integer for fixed batch size.
147
149
  max_concurrency (int, optional): Max concurrent API calls. Defaults to 8.
148
150
 
149
151
  Returns:
@@ -155,8 +157,8 @@ class AsyncBatchEmbeddings:
155
157
  cache=AsyncBatchingMapProxy(batch_size=batch_size, max_concurrency=max_concurrency),
156
158
  )
157
159
 
158
- @observe(_LOGGER)
159
160
  @backoff_async(exceptions=[RateLimitError, InternalServerError], scale=1, max_retries=12)
161
+ @observe(_LOGGER)
160
162
  async def _embed_chunk(self, inputs: List[str]) -> List[NDArray[np.float32]]:
161
163
  """Embed one minibatch of strings asynchronously.
162
164
 
@@ -186,4 +188,4 @@ class AsyncBatchEmbeddings:
186
188
  Returns:
187
189
  List[NDArray[np.float32]]: Embedding vectors aligned to ``inputs``.
188
190
  """
189
- return await self.cache.map(inputs, self._embed_chunk)
191
+ return await self.cache.map(inputs, self._embed_chunk) # type: ignore[arg-type]
@@ -1,13 +1,11 @@
1
1
  from dataclasses import dataclass
2
- from typing import Type, TypeVar
2
+ from typing import Generic, Type, TypeVar
3
3
 
4
- from pydantic import BaseModel
5
-
6
- ResponseFormat = TypeVar("ResponseFormat", bound=BaseModel | str)
4
+ ResponseFormat = TypeVar("ResponseFormat")
7
5
 
8
6
 
9
7
  @dataclass(frozen=True)
10
- class PreparedTask:
8
+ class PreparedTask(Generic[ResponseFormat]):
11
9
  """A data class representing a complete task configuration for OpenAI API calls.
12
10
 
13
11
  This class encapsulates all the necessary parameters for executing a task,
@@ -84,10 +82,10 @@ class OpenAIAPIKey:
84
82
  """Container for OpenAI API key configuration.
85
83
 
86
84
  Attributes:
87
- value (str): The API key for OpenAI services.
85
+ value (str | None): The API key for OpenAI services.
88
86
  """
89
87
 
90
- value: str
88
+ value: str | None
91
89
 
92
90
 
93
91
  @dataclass(frozen=True)
@@ -95,10 +93,10 @@ class AzureOpenAIAPIKey:
95
93
  """Container for Azure OpenAI API key configuration.
96
94
 
97
95
  Attributes:
98
- value (str): The API key for Azure OpenAI services.
96
+ value (str | None): The API key for Azure OpenAI services.
99
97
  """
100
98
 
101
- value: str
99
+ value: str | None
102
100
 
103
101
 
104
102
  @dataclass(frozen=True)
@@ -106,10 +104,10 @@ class AzureOpenAIBaseURL:
106
104
  """Container for Azure OpenAI base URL configuration.
107
105
 
108
106
  Attributes:
109
- value (str): The base URL for Azure OpenAI services.
107
+ value (str | None): The base URL for Azure OpenAI services.
110
108
  """
111
109
 
112
- value: str
110
+ value: str | None
113
111
 
114
112
 
115
113
  @dataclass(frozen=True)
@@ -21,7 +21,7 @@ class BatchSizeSuggester:
21
21
  min_duration: float = 30.0
22
22
  max_duration: float = 60.0
23
23
  step_ratio: float = 0.1
24
- sample_size: int = 10
24
+ sample_size: int = 4
25
25
  _history: List[PerformanceMetric] = field(default_factory=list)
26
26
  _lock: threading.RLock = field(default_factory=threading.RLock, repr=False)
27
27
  _batch_size_changed_at: datetime | None = field(default=None, init=False)
@@ -42,7 +42,7 @@ to easily interact with OpenAI APIs for tasks like generating responses or embed
42
42
  import inspect
43
43
  import json
44
44
  import logging
45
- from typing import Any, Awaitable, Callable, List, Type, TypeVar
45
+ from typing import Awaitable, Callable, List, Type, TypeVar
46
46
 
47
47
  import numpy as np
48
48
  import pandas as pd
@@ -184,6 +184,7 @@ class OpenAIVecSeriesAccessor:
184
184
  Args:
185
185
  cache (BatchingMapProxy[str, np.ndarray]): Pre-configured cache
186
186
  instance for managing API call batching and deduplication.
187
+ Set cache.batch_size=None to enable automatic batch size optimization.
187
188
 
188
189
  Returns:
189
190
  pandas.Series: Series whose values are ``np.ndarray`` objects
@@ -217,7 +218,7 @@ class OpenAIVecSeriesAccessor:
217
218
  self,
218
219
  instructions: str,
219
220
  response_format: Type[ResponseFormat] = str,
220
- batch_size: int = 128,
221
+ batch_size: int | None = None,
221
222
  temperature: float | None = 0.0,
222
223
  top_p: float = 1.0,
223
224
  show_progress: bool = False,
@@ -247,8 +248,9 @@ class OpenAIVecSeriesAccessor:
247
248
  instructions (str): System prompt prepended to every user message.
248
249
  response_format (Type[ResponseFormat], optional): Pydantic model or built‑in
249
250
  type the assistant should return. Defaults to ``str``.
250
- batch_size (int, optional): Number of prompts grouped into a single
251
- request. Defaults to ``128``.
251
+ batch_size (int | None, optional): Number of prompts grouped into a single
252
+ request. Defaults to ``None`` (automatic batch size optimization
253
+ based on execution time). Set to a positive integer for fixed batch size.
252
254
  temperature (float, optional): Sampling temperature. Defaults to ``0.0``.
253
255
  top_p (float, optional): Nucleus sampling parameter. Defaults to ``1.0``.
254
256
  show_progress (bool, optional): Show progress bar in Jupyter notebooks. Defaults to ``False``.
@@ -266,7 +268,7 @@ class OpenAIVecSeriesAccessor:
266
268
 
267
269
  def task_with_cache(
268
270
  self,
269
- task: PreparedTask,
271
+ task: PreparedTask[ResponseFormat],
270
272
  cache: BatchingMapProxy[str, ResponseFormat],
271
273
  ) -> pd.Series:
272
274
  """Execute a prepared task on every Series element using a provided cache.
@@ -280,6 +282,7 @@ class OpenAIVecSeriesAccessor:
280
282
  response format, and other parameters for processing the inputs.
281
283
  cache (BatchingMapProxy[str, ResponseFormat]): Pre-configured cache
282
284
  instance for managing API call batching and deduplication.
285
+ Set cache.batch_size=None to enable automatic batch size optimization.
283
286
 
284
287
  Returns:
285
288
  pandas.Series: Series whose values are instances of the task's
@@ -311,7 +314,7 @@ class OpenAIVecSeriesAccessor:
311
314
  )
312
315
  return pd.Series(client.parse(self._obj.tolist()), index=self._obj.index, name=self._obj.name)
313
316
 
314
- def task(self, task: PreparedTask, batch_size: int = 128, show_progress: bool = False) -> pd.Series:
317
+ def task(self, task: PreparedTask, batch_size: int | None = None, show_progress: bool = False) -> pd.Series:
315
318
  """Execute a prepared task on every Series element.
316
319
 
317
320
  This method applies a pre-configured task to each element in the Series,
@@ -343,8 +346,9 @@ class OpenAIVecSeriesAccessor:
343
346
  Args:
344
347
  task (PreparedTask): A pre-configured task containing instructions,
345
348
  response format, and other parameters for processing the inputs.
346
- batch_size (int, optional): Number of prompts grouped into a single
347
- request to optimize API usage. Defaults to 128.
349
+ batch_size (int | None, optional): Number of prompts grouped into a single
350
+ request to optimize API usage. Defaults to ``None`` (automatic batch size
351
+ optimization based on execution time). Set to a positive integer for fixed batch size.
348
352
  show_progress (bool, optional): Show progress bar in Jupyter notebooks. Defaults to ``False``.
349
353
 
350
354
  Returns:
@@ -356,7 +360,7 @@ class OpenAIVecSeriesAccessor:
356
360
  cache=BatchingMapProxy(batch_size=batch_size, show_progress=show_progress),
357
361
  )
358
362
 
359
- def embeddings(self, batch_size: int = 128, show_progress: bool = False) -> pd.Series:
363
+ def embeddings(self, batch_size: int | None = None, show_progress: bool = False) -> pd.Series:
360
364
  """Compute OpenAI embeddings for every Series element.
361
365
 
362
366
  Example:
@@ -378,8 +382,9 @@ class OpenAIVecSeriesAccessor:
378
382
  The default embedding model is `text-embedding-3-small`.
379
383
 
380
384
  Args:
381
- batch_size (int, optional): Number of inputs grouped into a
382
- single request. Defaults to ``128``.
385
+ batch_size (int | None, optional): Number of inputs grouped into a
386
+ single request. Defaults to ``None`` (automatic batch size optimization
387
+ based on execution time). Set to a positive integer for fixed batch size.
383
388
  show_progress (bool, optional): Show progress bar in Jupyter notebooks. Defaults to ``False``.
384
389
 
385
390
  Returns:
@@ -494,6 +499,7 @@ class OpenAIVecDataFrameAccessor:
494
499
  instructions (str): System prompt for the assistant.
495
500
  cache (BatchingMapProxy[str, ResponseFormat]): Pre-configured cache
496
501
  instance for managing API call batching and deduplication.
502
+ Set cache.batch_size=None to enable automatic batch size optimization.
497
503
  response_format (Type[ResponseFormat], optional): Desired Python type of the
498
504
  responses. Defaults to ``str``.
499
505
  temperature (float, optional): Sampling temperature. Defaults to ``0.0``.
@@ -538,7 +544,7 @@ class OpenAIVecDataFrameAccessor:
538
544
  self,
539
545
  instructions: str,
540
546
  response_format: Type[ResponseFormat] = str,
541
- batch_size: int = 128,
547
+ batch_size: int | None = None,
542
548
  temperature: float | None = 0.0,
543
549
  top_p: float = 1.0,
544
550
  show_progress: bool = False,
@@ -573,8 +579,9 @@ class OpenAIVecDataFrameAccessor:
573
579
  instructions (str): System prompt for the assistant.
574
580
  response_format (Type[ResponseFormat], optional): Desired Python type of the
575
581
  responses. Defaults to ``str``.
576
- batch_size (int, optional): Number of requests sent in one batch.
577
- Defaults to ``128``.
582
+ batch_size (int | None, optional): Number of requests sent in one batch.
583
+ Defaults to ``None`` (automatic batch size optimization
584
+ based on execution time). Set to a positive integer for fixed batch size.
578
585
  temperature (float, optional): Sampling temperature. Defaults to ``0.0``.
579
586
  top_p (float, optional): Nucleus sampling parameter. Defaults to ``1.0``.
580
587
  show_progress (bool, optional): Show progress bar in Jupyter notebooks. Defaults to ``False``.
@@ -590,7 +597,7 @@ class OpenAIVecDataFrameAccessor:
590
597
  top_p=top_p,
591
598
  )
592
599
 
593
- def task(self, task: PreparedTask, batch_size: int = 128, show_progress: bool = False) -> pd.Series:
600
+ def task(self, task: PreparedTask, batch_size: int | None = None, show_progress: bool = False) -> pd.Series:
594
601
  """Execute a prepared task on each DataFrame row after serialising it to JSON.
595
602
 
596
603
  This method applies a pre-configured task to each row in the DataFrame,
@@ -618,8 +625,9 @@ class OpenAIVecDataFrameAccessor:
618
625
  Args:
619
626
  task (PreparedTask): A pre-configured task containing instructions,
620
627
  response format, and other parameters for processing the inputs.
621
- batch_size (int, optional): Number of requests sent in one batch
622
- to optimize API usage. Defaults to 128.
628
+ batch_size (int | None, optional): Number of requests sent in one batch
629
+ to optimize API usage. Defaults to ``None`` (automatic batch size
630
+ optimization based on execution time). Set to a positive integer for fixed batch size.
623
631
  show_progress (bool, optional): Show progress bar in Jupyter notebooks. Defaults to ``False``.
624
632
 
625
633
  Returns:
@@ -634,7 +642,7 @@ class OpenAIVecDataFrameAccessor:
634
642
  )
635
643
  )
636
644
 
637
- def fillna(self, target_column_name: str, max_examples: int = 500, batch_size: int = 128) -> pd.DataFrame:
645
+ def fillna(self, target_column_name: str, max_examples: int = 500, batch_size: int | None = None) -> pd.DataFrame:
638
646
  """Fill missing values in a DataFrame column using AI-powered inference.
639
647
 
640
648
  This method uses machine learning to intelligently fill missing (NaN) values
@@ -648,8 +656,9 @@ class OpenAIVecDataFrameAccessor:
648
656
  max_examples (int, optional): The maximum number of example rows to use
649
657
  for context when predicting missing values. Higher values may improve
650
658
  accuracy but increase API costs and processing time. Defaults to 500.
651
- batch_size (int, optional): Number of requests sent in one batch
652
- to optimize API usage. Defaults to 128.
659
+ batch_size (int | None, optional): Number of requests sent in one batch
660
+ to optimize API usage. Defaults to ``None`` (automatic batch size
661
+ optimization based on execution time). Set to a positive integer for fixed batch size.
653
662
 
654
663
  Returns:
655
664
  pandas.DataFrame: A new DataFrame with missing values filled in the target
@@ -721,7 +730,7 @@ class OpenAIVecDataFrameAccessor:
721
730
  return self._obj.apply(
722
731
  lambda row: np.dot(row[col1], row[col2]) / (np.linalg.norm(row[col1]) * np.linalg.norm(row[col2])),
723
732
  axis=1,
724
- ).rename("similarity")
733
+ ).rename("similarity") # type: ignore[arg-type]
725
734
 
726
735
 
727
736
  @pd.api.extensions.register_series_accessor("aio")
@@ -750,6 +759,7 @@ class AsyncOpenAIVecSeriesAccessor:
750
759
  instructions (str): System prompt prepended to every user message.
751
760
  cache (AsyncBatchingMapProxy[str, ResponseFormat]): Pre-configured cache
752
761
  instance for managing API call batching and deduplication.
762
+ Set cache.batch_size=None to enable automatic batch size optimization.
753
763
  response_format (Type[ResponseFormat], optional): Pydantic model or built‑in
754
764
  type the assistant should return. Defaults to ``str``.
755
765
  temperature (float, optional): Sampling temperature. Defaults to ``0.0``.
@@ -804,6 +814,7 @@ class AsyncOpenAIVecSeriesAccessor:
804
814
  Args:
805
815
  cache (AsyncBatchingMapProxy[str, np.ndarray]): Pre-configured cache
806
816
  instance for managing API call batching and deduplication.
817
+ Set cache.batch_size=None to enable automatic batch size optimization.
807
818
 
808
819
  Returns:
809
820
  pandas.Series: Series whose values are ``np.ndarray`` objects
@@ -844,7 +855,7 @@ class AsyncOpenAIVecSeriesAccessor:
844
855
 
845
856
  async def task_with_cache(
846
857
  self,
847
- task: PreparedTask,
858
+ task: PreparedTask[ResponseFormat],
848
859
  cache: AsyncBatchingMapProxy[str, ResponseFormat],
849
860
  ) -> pd.Series:
850
861
  """Execute a prepared task on every Series element using a provided cache (asynchronously).
@@ -859,6 +870,7 @@ class AsyncOpenAIVecSeriesAccessor:
859
870
  response format, and other parameters for processing the inputs.
860
871
  cache (AsyncBatchingMapProxy[str, ResponseFormat]): Pre-configured cache
861
872
  instance for managing API call batching and deduplication.
873
+ Set cache.batch_size=None to enable automatic batch size optimization.
862
874
 
863
875
  Returns:
864
876
  pandas.Series: Series whose values are instances of the task's
@@ -902,7 +914,7 @@ class AsyncOpenAIVecSeriesAccessor:
902
914
  self,
903
915
  instructions: str,
904
916
  response_format: Type[ResponseFormat] = str,
905
- batch_size: int = 128,
917
+ batch_size: int | None = None,
906
918
  temperature: float | None = 0.0,
907
919
  top_p: float = 1.0,
908
920
  max_concurrency: int = 8,
@@ -934,8 +946,9 @@ class AsyncOpenAIVecSeriesAccessor:
934
946
  instructions (str): System prompt prepended to every user message.
935
947
  response_format (Type[ResponseFormat], optional): Pydantic model or built‑in
936
948
  type the assistant should return. Defaults to ``str``.
937
- batch_size (int, optional): Number of prompts grouped into a single
938
- request. Defaults to ``128``.
949
+ batch_size (int | None, optional): Number of prompts grouped into a single
950
+ request. Defaults to ``None`` (automatic batch size optimization
951
+ based on execution time). Set to a positive integer for fixed batch size.
939
952
  temperature (float, optional): Sampling temperature. Defaults to ``0.0``.
940
953
  top_p (float, optional): Nucleus sampling parameter. Defaults to ``1.0``.
941
954
  max_concurrency (int, optional): Maximum number of concurrent
@@ -959,7 +972,7 @@ class AsyncOpenAIVecSeriesAccessor:
959
972
  )
960
973
 
961
974
  async def embeddings(
962
- self, batch_size: int = 128, max_concurrency: int = 8, show_progress: bool = False
975
+ self, batch_size: int | None = None, max_concurrency: int = 8, show_progress: bool = False
963
976
  ) -> pd.Series:
964
977
  """Compute OpenAI embeddings for every Series element (asynchronously).
965
978
 
@@ -983,8 +996,9 @@ class AsyncOpenAIVecSeriesAccessor:
983
996
  The default embedding model is `text-embedding-3-small`.
984
997
 
985
998
  Args:
986
- batch_size (int, optional): Number of inputs grouped into a
987
- single request. Defaults to ``128``.
999
+ batch_size (int | None, optional): Number of inputs grouped into a
1000
+ single request. Defaults to ``None`` (automatic batch size optimization
1001
+ based on execution time). Set to a positive integer for fixed batch size.
988
1002
  max_concurrency (int, optional): Maximum number of concurrent
989
1003
  requests. Defaults to ``8``.
990
1004
  show_progress (bool, optional): Show progress bar in Jupyter notebooks. Defaults to ``False``.
@@ -1003,7 +1017,7 @@ class AsyncOpenAIVecSeriesAccessor:
1003
1017
  )
1004
1018
 
1005
1019
  async def task(
1006
- self, task: PreparedTask, batch_size: int = 128, max_concurrency: int = 8, show_progress: bool = False
1020
+ self, task: PreparedTask, batch_size: int | None = None, max_concurrency: int = 8, show_progress: bool = False
1007
1021
  ) -> pd.Series:
1008
1022
  """Execute a prepared task on every Series element (asynchronously).
1009
1023
 
@@ -1037,8 +1051,9 @@ class AsyncOpenAIVecSeriesAccessor:
1037
1051
  Args:
1038
1052
  task (PreparedTask): A pre-configured task containing instructions,
1039
1053
  response format, and other parameters for processing the inputs.
1040
- batch_size (int, optional): Number of prompts grouped into a single
1041
- request to optimize API usage. Defaults to 128.
1054
+ batch_size (int | None, optional): Number of prompts grouped into a single
1055
+ request to optimize API usage. Defaults to ``None`` (automatic batch size
1056
+ optimization based on execution time). Set to a positive integer for fixed batch size.
1042
1057
  max_concurrency (int, optional): Maximum number of concurrent
1043
1058
  requests. Defaults to 8.
1044
1059
  show_progress (bool, optional): Show progress bar in Jupyter notebooks. Defaults to ``False``.
@@ -1084,6 +1099,7 @@ class AsyncOpenAIVecDataFrameAccessor:
1084
1099
  instructions (str): System prompt for the assistant.
1085
1100
  cache (AsyncBatchingMapProxy[str, ResponseFormat]): Pre-configured cache
1086
1101
  instance for managing API call batching and deduplication.
1102
+ Set cache.batch_size=None to enable automatic batch size optimization.
1087
1103
  response_format (Type[ResponseFormat], optional): Desired Python type of the
1088
1104
  responses. Defaults to ``str``.
1089
1105
  temperature (float, optional): Sampling temperature. Defaults to ``0.0``.
@@ -1134,7 +1150,7 @@ class AsyncOpenAIVecDataFrameAccessor:
1134
1150
  self,
1135
1151
  instructions: str,
1136
1152
  response_format: Type[ResponseFormat] = str,
1137
- batch_size: int = 128,
1153
+ batch_size: int | None = None,
1138
1154
  temperature: float | None = 0.0,
1139
1155
  top_p: float = 1.0,
1140
1156
  max_concurrency: int = 8,
@@ -1171,8 +1187,9 @@ class AsyncOpenAIVecDataFrameAccessor:
1171
1187
  instructions (str): System prompt for the assistant.
1172
1188
  response_format (Type[ResponseFormat], optional): Desired Python type of the
1173
1189
  responses. Defaults to ``str``.
1174
- batch_size (int, optional): Number of requests sent in one batch.
1175
- Defaults to ``128``.
1190
+ batch_size (int | None, optional): Number of requests sent in one batch.
1191
+ Defaults to ``None`` (automatic batch size optimization
1192
+ based on execution time). Set to a positive integer for fixed batch size.
1176
1193
  temperature (float, optional): Sampling temperature. Defaults to ``0.0``.
1177
1194
  top_p (float, optional): Nucleus sampling parameter. Defaults to ``1.0``.
1178
1195
  max_concurrency (int, optional): Maximum number of concurrent
@@ -1196,7 +1213,7 @@ class AsyncOpenAIVecDataFrameAccessor:
1196
1213
  )
1197
1214
 
1198
1215
  async def task(
1199
- self, task: PreparedTask, batch_size: int = 128, max_concurrency: int = 8, show_progress: bool = False
1216
+ self, task: PreparedTask, batch_size: int | None = None, max_concurrency: int = 8, show_progress: bool = False
1200
1217
  ) -> pd.Series:
1201
1218
  """Execute a prepared task on each DataFrame row after serialising it to JSON (asynchronously).
1202
1219
 
@@ -1235,8 +1252,9 @@ class AsyncOpenAIVecDataFrameAccessor:
1235
1252
  Args:
1236
1253
  task (PreparedTask): A pre-configured task containing instructions,
1237
1254
  response format, and other parameters for processing the inputs.
1238
- batch_size (int, optional): Number of requests sent in one batch
1239
- to optimize API usage. Defaults to 128.
1255
+ batch_size (int | None, optional): Number of requests sent in one batch
1256
+ to optimize API usage. Defaults to ``None`` (automatic batch size
1257
+ optimization based on execution time). Set to a positive integer for fixed batch size.
1240
1258
  max_concurrency (int, optional): Maximum number of concurrent
1241
1259
  requests. Defaults to 8.
1242
1260
  show_progress (bool, optional): Show progress bar in Jupyter notebooks. Defaults to ``False``.
@@ -1286,7 +1304,7 @@ class AsyncOpenAIVecDataFrameAccessor:
1286
1304
  else:
1287
1305
  return result
1288
1306
 
1289
- async def assign(self, **kwargs: Any) -> pd.DataFrame:
1307
+ async def assign(self, **kwargs) -> pd.DataFrame:
1290
1308
  """Asynchronously assign new columns to the DataFrame, evaluating sequentially.
1291
1309
 
1292
1310
  This method extends pandas' `assign` method by supporting asynchronous
@@ -1321,7 +1339,7 @@ class AsyncOpenAIVecDataFrameAccessor:
1321
1339
  ```
1322
1340
 
1323
1341
  Args:
1324
- **kwargs: Any. Column names as keys and either static values or callables
1342
+ **kwargs: Column names as keys and either static values or callables
1325
1343
  (synchronous or asynchronous) as values.
1326
1344
 
1327
1345
  Returns:
@@ -1346,7 +1364,7 @@ class AsyncOpenAIVecDataFrameAccessor:
1346
1364
  return df_current
1347
1365
 
1348
1366
  async def fillna(
1349
- self, target_column_name: str, max_examples: int = 500, batch_size: int = 128, max_concurrency: int = 8
1367
+ self, target_column_name: str, max_examples: int = 500, batch_size: int | None = None, max_concurrency: int = 8
1350
1368
  ) -> pd.DataFrame:
1351
1369
  """Fill missing values in a DataFrame column using AI-powered inference (asynchronously).
1352
1370
 
@@ -1361,8 +1379,9 @@ class AsyncOpenAIVecDataFrameAccessor:
1361
1379
  max_examples (int, optional): The maximum number of example rows to use
1362
1380
  for context when predicting missing values. Higher values may improve
1363
1381
  accuracy but increase API costs and processing time. Defaults to 500.
1364
- batch_size (int, optional): Number of requests sent in one batch
1365
- to optimize API usage. Defaults to 128.
1382
+ batch_size (int | None, optional): Number of requests sent in one batch
1383
+ to optimize API usage. Defaults to ``None`` (automatic batch size
1384
+ optimization based on execution time). Set to a positive integer for fixed batch size.
1366
1385
  max_concurrency (int, optional): Maximum number of concurrent
1367
1386
  requests. Defaults to 8.
1368
1387