lm-deluge 0.0.23__tar.gz → 0.0.25__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.

Potentially problematic release.


This version of lm-deluge might be problematic. Click here for more details.

Files changed (62) hide show
  1. {lm_deluge-0.0.23/src/lm_deluge.egg-info → lm_deluge-0.0.25}/PKG-INFO +1 -1
  2. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/pyproject.toml +1 -1
  3. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/batches.py +131 -42
  4. {lm_deluge-0.0.23 → lm_deluge-0.0.25/src/lm_deluge.egg-info}/PKG-INFO +1 -1
  5. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/LICENSE +0 -0
  6. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/README.md +0 -0
  7. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/setup.cfg +0 -0
  8. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/__init__.py +0 -0
  9. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/agent.py +0 -0
  10. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/api_requests/__init__.py +0 -0
  11. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/api_requests/anthropic.py +0 -0
  12. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/api_requests/base.py +0 -0
  13. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/api_requests/bedrock.py +0 -0
  14. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/api_requests/common.py +0 -0
  15. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/api_requests/deprecated/bedrock.py +0 -0
  16. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/api_requests/deprecated/cohere.py +0 -0
  17. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/api_requests/deprecated/deepseek.py +0 -0
  18. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/api_requests/deprecated/mistral.py +0 -0
  19. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/api_requests/deprecated/vertex.py +0 -0
  20. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/api_requests/gemini.py +0 -0
  21. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/api_requests/mistral.py +0 -0
  22. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/api_requests/openai.py +0 -0
  23. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/api_requests/response.py +0 -0
  24. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/built_in_tools/anthropic/__init__.py +0 -0
  25. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/built_in_tools/anthropic/bash.py +0 -0
  26. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/built_in_tools/anthropic/computer_use.py +0 -0
  27. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/built_in_tools/anthropic/editor.py +0 -0
  28. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/built_in_tools/base.py +0 -0
  29. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/built_in_tools/openai.py +0 -0
  30. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/cache.py +0 -0
  31. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/client.py +0 -0
  32. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/config.py +0 -0
  33. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/embed.py +0 -0
  34. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/errors.py +0 -0
  35. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/file.py +0 -0
  36. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/gemini_limits.py +0 -0
  37. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/image.py +0 -0
  38. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/llm_tools/__init__.py +0 -0
  39. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/llm_tools/classify.py +0 -0
  40. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/llm_tools/extract.py +0 -0
  41. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/llm_tools/locate.py +0 -0
  42. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/llm_tools/ocr.py +0 -0
  43. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/llm_tools/score.py +0 -0
  44. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/llm_tools/translate.py +0 -0
  45. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/models.py +0 -0
  46. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/prompt.py +0 -0
  47. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/request_context.py +0 -0
  48. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/rerank.py +0 -0
  49. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/tool.py +0 -0
  50. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/tracker.py +0 -0
  51. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/usage.py +0 -0
  52. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/util/json.py +0 -0
  53. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/util/logprobs.py +0 -0
  54. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/util/spatial.py +0 -0
  55. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/util/validation.py +0 -0
  56. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge/util/xml.py +0 -0
  57. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge.egg-info/SOURCES.txt +0 -0
  58. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge.egg-info/dependency_links.txt +0 -0
  59. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge.egg-info/requires.txt +0 -0
  60. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/src/lm_deluge.egg-info/top_level.txt +0 -0
  61. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/tests/test_builtin_tools.py +0 -0
  62. {lm_deluge-0.0.23 → lm_deluge-0.0.25}/tests/test_native_mcp_server.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lm_deluge
3
- Version: 0.0.23
3
+ Version: 0.0.25
4
4
  Summary: Python utility for using LLM API models.
5
5
  Author-email: Benjamin Anderson <ben@trytaylor.ai>
6
6
  Requires-Python: >=3.10
@@ -3,7 +3,7 @@ requires = ["setuptools", "wheel"]
3
3
 
4
4
  [project]
5
5
  name = "lm_deluge"
6
- version = "0.0.23"
6
+ version = "0.0.25"
7
7
  authors = [{ name = "Benjamin Anderson", email = "ben@trytaylor.ai" }]
8
8
  description = "Python utility for using LLM API models."
9
9
  readme = "README.md"
@@ -169,7 +169,8 @@ async def submit_batches_oa(
169
169
  batch_size: int = 50_000,
170
170
  ):
171
171
  """Write OpenAI batch requests to a file and submit."""
172
- BATCH_SIZE = batch_size
172
+ MAX_BATCH_SIZE_BYTES = 200 * 1024 * 1024 # 200MB
173
+ MAX_BATCH_SIZE_ITEMS = batch_size
173
174
 
174
175
  prompts = prompts_to_conversations(prompts)
175
176
  if any(p is None for p in prompts):
@@ -178,29 +179,71 @@ async def submit_batches_oa(
178
179
  model_obj = APIModel.from_registry(model)
179
180
 
180
181
  tasks = []
182
+ current_batch = []
183
+ current_batch_size = 0
184
+ # current_batch_start_idx = 0
185
+
186
+ for idx, prompt in enumerate(prompts):
187
+ assert isinstance(prompt, Conversation)
188
+ context = RequestContext(
189
+ task_id=idx,
190
+ model_name=model,
191
+ prompt=prompt,
192
+ sampling_params=sampling_params,
193
+ )
194
+ request = {
195
+ "custom_id": str(idx),
196
+ "method": "POST",
197
+ "url": "/v1/chat/completions",
198
+ "body": await _build_oa_chat_request(model_obj, context),
199
+ }
181
200
 
182
- for start in range(0, len(prompts), BATCH_SIZE):
183
- batch_prompts = prompts[start : start + BATCH_SIZE]
184
- with tempfile.NamedTemporaryFile(mode="w+", suffix=".jsonl", delete=False) as f:
185
- for idx, prompt in enumerate(batch_prompts, start=start):
186
- assert isinstance(prompt, Conversation)
187
- context = RequestContext(
188
- task_id=idx,
189
- model_name=model,
190
- prompt=prompt,
191
- sampling_params=sampling_params,
192
- )
193
- request = {
194
- "custom_id": str(idx),
195
- "method": "POST",
196
- "url": "/v1/chat/completions",
197
- "body": _build_oa_chat_request(model_obj, context),
198
- }
199
- json.dump(request, f)
200
- f.write("\n")
201
-
202
- file_path = f.name
203
-
201
+ # Calculate size of this request
202
+ request_json = json.dumps(request) + "\n"
203
+ request_size = len(request_json.encode("utf-8"))
204
+
205
+ # Check if adding this request would exceed limits
206
+ would_exceed_size = current_batch_size + request_size > MAX_BATCH_SIZE_BYTES
207
+ would_exceed_items = len(current_batch) >= MAX_BATCH_SIZE_ITEMS
208
+
209
+ if current_batch and (would_exceed_size or would_exceed_items):
210
+ # Submit current batch
211
+ def write_batch_file():
212
+ with tempfile.NamedTemporaryFile(
213
+ mode="w+", suffix=".jsonl", delete=False
214
+ ) as f:
215
+ for batch_request in current_batch:
216
+ json.dump(batch_request, f)
217
+ f.write("\n")
218
+ print("wrote", len(current_batch), "items")
219
+ return f.name
220
+
221
+ file_path = await asyncio.to_thread(write_batch_file)
222
+ tasks.append(asyncio.create_task(submit_batch_oa(file_path)))
223
+
224
+ # Start new batch
225
+ current_batch = []
226
+ current_batch_size = 0
227
+ # current_batch_start_idx = idx
228
+
229
+ # Add request to current batch
230
+ current_batch.append(request)
231
+ current_batch_size += request_size
232
+
233
+ # Submit final batch if it has items
234
+ if current_batch:
235
+
236
+ def write_final_batch_file():
237
+ with tempfile.NamedTemporaryFile(
238
+ mode="w+", suffix=".jsonl", delete=False
239
+ ) as f:
240
+ for batch_request in current_batch:
241
+ json.dump(batch_request, f)
242
+ f.write("\n")
243
+ print("wrote", len(current_batch), "items")
244
+ return f.name
245
+
246
+ file_path = await asyncio.to_thread(write_final_batch_file)
204
247
  tasks.append(asyncio.create_task(submit_batch_oa(file_path)))
205
248
 
206
249
  batch_ids = await asyncio.gather(*tasks)
@@ -229,34 +272,80 @@ async def submit_batches_anthropic(
229
272
 
230
273
  Returns: batch_ids (list[str])
231
274
  """
275
+ MAX_BATCH_SIZE_BYTES = 200 * 1024 * 1024 # 200MB
276
+ MAX_BATCH_SIZE_ITEMS = batch_size
232
277
 
233
278
  # Convert prompts to Conversations
234
279
  prompts = prompts_to_conversations(prompts)
235
280
 
236
281
  request_headers = None
237
- BATCH_SIZE = batch_size
238
282
  batch_tasks = []
239
-
240
- for start in range(0, len(prompts), BATCH_SIZE):
241
- batch_prompts = prompts[start : start + BATCH_SIZE]
242
- with tempfile.NamedTemporaryFile(mode="w+", suffix=".jsonl", delete=False) as f:
243
- for idx, prompt in enumerate(batch_prompts, start=start):
244
- assert isinstance(prompt, Conversation)
245
- context = RequestContext(
246
- task_id=idx,
247
- model_name=model,
248
- prompt=prompt,
249
- sampling_params=sampling_params,
250
- cache=cache,
251
- )
252
- request_body, request_headers = _build_anthropic_request(
253
- APIModel.from_registry(model), context
283
+ current_batch = []
284
+ current_batch_size = 0
285
+
286
+ for idx, prompt in enumerate(prompts):
287
+ assert isinstance(prompt, Conversation)
288
+ context = RequestContext(
289
+ task_id=idx,
290
+ model_name=model,
291
+ prompt=prompt,
292
+ sampling_params=sampling_params,
293
+ cache=cache,
294
+ )
295
+ request_body, request_headers = _build_anthropic_request(
296
+ APIModel.from_registry(model), context
297
+ )
298
+ request = {"custom_id": str(idx), "params": request_body}
299
+
300
+ # Calculate size of this request
301
+ request_json = json.dumps(request) + "\n"
302
+ request_size = len(request_json.encode("utf-8"))
303
+
304
+ # Check if adding this request would exceed limits
305
+ would_exceed_size = current_batch_size + request_size > MAX_BATCH_SIZE_BYTES
306
+ would_exceed_items = len(current_batch) >= MAX_BATCH_SIZE_ITEMS
307
+
308
+ if current_batch and (would_exceed_size or would_exceed_items):
309
+ # Submit current batch
310
+ def write_batch_file():
311
+ with tempfile.NamedTemporaryFile(
312
+ mode="w+", suffix=".jsonl", delete=False
313
+ ) as f:
314
+ for batch_request in current_batch:
315
+ json.dump(batch_request, f)
316
+ f.write("\n")
317
+ print("wrote", len(current_batch), "items")
318
+ return f.name
319
+
320
+ file_path = await asyncio.to_thread(write_batch_file)
321
+ batch_tasks.append(
322
+ asyncio.create_task(
323
+ _submit_anthropic_batch(file_path, request_headers, model) # type: ignore
254
324
  )
255
- json.dump({"custom_id": str(idx), "params": request_body}, f)
256
- f.write("\n")
325
+ )
326
+
327
+ # Start new batch
328
+ current_batch = []
329
+ current_batch_size = 0
330
+
331
+ # Add request to current batch
332
+ current_batch.append(request)
333
+ current_batch_size += request_size
334
+
335
+ # Submit final batch if it has items
336
+ if current_batch:
257
337
 
258
- file_path = f.name
338
+ def write_final_batch_file():
339
+ with tempfile.NamedTemporaryFile(
340
+ mode="w+", suffix=".jsonl", delete=False
341
+ ) as f:
342
+ for batch_request in current_batch:
343
+ json.dump(batch_request, f)
344
+ f.write("\n")
345
+ print("wrote", len(current_batch), "items")
346
+ return f.name
259
347
 
348
+ file_path = await asyncio.to_thread(write_final_batch_file)
260
349
  batch_tasks.append(
261
350
  asyncio.create_task(
262
351
  _submit_anthropic_batch(file_path, request_headers, model) # type: ignore
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lm_deluge
3
- Version: 0.0.23
3
+ Version: 0.0.25
4
4
  Summary: Python utility for using LLM API models.
5
5
  Author-email: Benjamin Anderson <ben@trytaylor.ai>
6
6
  Requires-Python: >=3.10
File without changes
File without changes
File without changes