lm-deluge 0.0.44__tar.gz → 0.0.46__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.
- {lm_deluge-0.0.44/src/lm_deluge.egg-info → lm_deluge-0.0.46}/PKG-INFO +1 -1
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/pyproject.toml +1 -1
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/client.py +41 -42
- lm_deluge-0.0.46/src/lm_deluge/presets/cerebras.py +17 -0
- lm_deluge-0.0.46/src/lm_deluge/presets/meta.py +13 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/prompt.py +19 -2
- {lm_deluge-0.0.44 → lm_deluge-0.0.46/src/lm_deluge.egg-info}/PKG-INFO +1 -1
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge.egg-info/SOURCES.txt +2 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/LICENSE +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/README.md +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/setup.cfg +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/__init__.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/agent.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/api_requests/__init__.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/api_requests/anthropic.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/api_requests/base.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/api_requests/bedrock.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/api_requests/common.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/api_requests/deprecated/bedrock.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/api_requests/deprecated/cohere.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/api_requests/deprecated/deepseek.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/api_requests/deprecated/mistral.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/api_requests/deprecated/vertex.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/api_requests/gemini.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/api_requests/mistral.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/api_requests/openai.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/api_requests/response.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/batches.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/built_in_tools/anthropic/__init__.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/built_in_tools/anthropic/bash.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/built_in_tools/anthropic/computer_use.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/built_in_tools/anthropic/editor.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/built_in_tools/base.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/built_in_tools/openai.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/cache.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/cli.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/config.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/embed.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/errors.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/file.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/gemini_limits.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/image.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/llm_tools/__init__.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/llm_tools/classify.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/llm_tools/extract.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/llm_tools/locate.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/llm_tools/ocr.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/llm_tools/score.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/llm_tools/translate.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/models/__init__.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/models/anthropic.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/models/bedrock.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/models/cerebras.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/models/cohere.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/models/deepseek.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/models/fireworks.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/models/google.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/models/grok.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/models/groq.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/models/meta.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/models/mistral.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/models/openai.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/models/openrouter.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/models/together.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/request_context.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/rerank.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/tool.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/tracker.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/usage.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/util/harmony.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/util/json.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/util/logprobs.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/util/spatial.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/util/validation.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/util/xml.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge.egg-info/dependency_links.txt +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge.egg-info/requires.txt +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge.egg-info/top_level.txt +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/tests/test_builtin_tools.py +0 -0
- {lm_deluge-0.0.44 → lm_deluge-0.0.46}/tests/test_native_mcp_server.py +0 -0
|
@@ -217,17 +217,19 @@ class _LLMClient(BaseModel):
|
|
|
217
217
|
self, num_tokens: int, tracker: StatusTracker, *, retry: bool = False
|
|
218
218
|
):
|
|
219
219
|
while True:
|
|
220
|
+
# Enforce cooldown first, regardless of current capacity.
|
|
221
|
+
cooldown = tracker.seconds_to_pause
|
|
222
|
+
if cooldown > 0:
|
|
223
|
+
print(f"Pausing for {cooldown} seconds to cool down.")
|
|
224
|
+
await asyncio.sleep(cooldown)
|
|
225
|
+
continue
|
|
226
|
+
|
|
220
227
|
async with self._capacity_lock:
|
|
221
228
|
if tracker.check_capacity(num_tokens, retry=retry):
|
|
222
229
|
tracker.set_limiting_factor(None)
|
|
223
230
|
return
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
if seconds_to_pause > 0:
|
|
227
|
-
print(f"Pausing for {seconds_to_pause} seconds to cool down.")
|
|
228
|
-
await asyncio.sleep(seconds_to_pause)
|
|
229
|
-
else:
|
|
230
|
-
await asyncio.sleep(30.0 / self.max_requests_per_minute)
|
|
231
|
+
# Idle wait before next capacity check. Aim for ~RPM spacing.
|
|
232
|
+
await asyncio.sleep(max(60.0 / self.max_requests_per_minute, 0.01))
|
|
231
233
|
|
|
232
234
|
async def _execute_request(self, context: RequestContext) -> APIResponse:
|
|
233
235
|
"""Create and send a single API request using the provided context."""
|
|
@@ -363,7 +365,7 @@ class _LLMClient(BaseModel):
|
|
|
363
365
|
# Create retry queue for failed requests
|
|
364
366
|
retry_queue: asyncio.Queue[RequestContext] = asyncio.Queue()
|
|
365
367
|
|
|
366
|
-
# Calculate sleep time for rate limiting
|
|
368
|
+
# Calculate sleep time for rate limiting (legacy; gating happens in _wait_for_capacity)
|
|
367
369
|
seconds_to_sleep_each_loop = (60.0 * 0.9) / tracker.max_requests_per_minute
|
|
368
370
|
|
|
369
371
|
# Main dispatch loop - using original pattern but with all prompts
|
|
@@ -403,40 +405,37 @@ class _LLMClient(BaseModel):
|
|
|
403
405
|
except StopIteration:
|
|
404
406
|
prompts_not_finished = False
|
|
405
407
|
|
|
406
|
-
#
|
|
407
|
-
tracker.update_capacity()
|
|
408
|
-
|
|
409
|
-
# Dispatch if capacity available - original logic
|
|
408
|
+
# Dispatch using shared capacity gate (consistent with start_nowait)
|
|
410
409
|
if next_context:
|
|
411
|
-
|
|
412
|
-
|
|
410
|
+
# Wait here until we have capacity to launch this context
|
|
411
|
+
await self._wait_for_capacity(
|
|
412
|
+
next_context.num_tokens, tracker, retry=next_is_retry
|
|
413
|
+
)
|
|
414
|
+
|
|
415
|
+
# Launch simplified request processing
|
|
416
|
+
async def process_and_store(ctx: RequestContext):
|
|
417
|
+
try:
|
|
418
|
+
response = await self.process_single_request(ctx, retry_queue)
|
|
419
|
+
results[ctx.task_id] = response
|
|
420
|
+
except Exception as e:
|
|
421
|
+
# Create an error response for validation errors and other exceptions
|
|
422
|
+
error_response = APIResponse(
|
|
423
|
+
id=ctx.task_id,
|
|
424
|
+
model_internal=ctx.model_name,
|
|
425
|
+
prompt=ctx.prompt,
|
|
426
|
+
sampling_params=ctx.sampling_params,
|
|
427
|
+
status_code=None,
|
|
428
|
+
is_error=True,
|
|
429
|
+
error_message=str(e),
|
|
430
|
+
)
|
|
431
|
+
results[ctx.task_id] = error_response
|
|
432
|
+
# Mark task as completed so the main loop can finish
|
|
433
|
+
if ctx.status_tracker:
|
|
434
|
+
ctx.status_tracker.task_failed(ctx.task_id)
|
|
413
435
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
response = await self.process_single_request(
|
|
418
|
-
ctx, retry_queue
|
|
419
|
-
)
|
|
420
|
-
results[ctx.task_id] = response
|
|
421
|
-
except Exception as e:
|
|
422
|
-
# Create an error response for validation errors and other exceptions
|
|
423
|
-
error_response = APIResponse(
|
|
424
|
-
id=ctx.task_id,
|
|
425
|
-
model_internal=ctx.model_name,
|
|
426
|
-
prompt=ctx.prompt,
|
|
427
|
-
sampling_params=ctx.sampling_params,
|
|
428
|
-
status_code=None,
|
|
429
|
-
is_error=True,
|
|
430
|
-
error_message=str(e),
|
|
431
|
-
)
|
|
432
|
-
results[ctx.task_id] = error_response
|
|
433
|
-
# Mark task as completed so the main loop can finish
|
|
434
|
-
if ctx.status_tracker:
|
|
435
|
-
ctx.status_tracker.task_failed(ctx.task_id)
|
|
436
|
-
|
|
437
|
-
asyncio.create_task(process_and_store(next_context))
|
|
438
|
-
next_context = None # Reset after successful dispatch
|
|
439
|
-
next_is_retry = False
|
|
436
|
+
asyncio.create_task(process_and_store(next_context))
|
|
437
|
+
next_context = None # Reset after successful dispatch
|
|
438
|
+
next_is_retry = False
|
|
440
439
|
|
|
441
440
|
# Update progress - original logic
|
|
442
441
|
tracker.update_pbar()
|
|
@@ -448,8 +447,8 @@ class _LLMClient(BaseModel):
|
|
|
448
447
|
) and retry_queue.empty():
|
|
449
448
|
break
|
|
450
449
|
|
|
451
|
-
#
|
|
452
|
-
await asyncio.sleep(seconds_to_sleep_each_loop
|
|
450
|
+
# Yield briefly to allow in-flight tasks to progress
|
|
451
|
+
await asyncio.sleep(min(0.01, seconds_to_sleep_each_loop))
|
|
453
452
|
|
|
454
453
|
if not tracker_preopened:
|
|
455
454
|
self.close()
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from lm_deluge import LLMClient
|
|
2
|
+
|
|
3
|
+
mixture_of_cerebras = LLMClient(
|
|
4
|
+
[
|
|
5
|
+
"gpt-oss-120b-cerebras",
|
|
6
|
+
"llama-4-scout-cerebras",
|
|
7
|
+
"llama-3.3-70b-cerebras",
|
|
8
|
+
"qwen-3-32b-cerebras",
|
|
9
|
+
"llama-4-maverick-cerebras",
|
|
10
|
+
"qwen-3-235b-instruct-cerebras",
|
|
11
|
+
"qwen-3-235b-thinking-cerebras",
|
|
12
|
+
"qwen-3-coder-cerebras",
|
|
13
|
+
],
|
|
14
|
+
model_weights=[3, 3, 3, 3, 3, 3, 3, 1],
|
|
15
|
+
max_requests_per_minute=250,
|
|
16
|
+
max_tokens_per_minute=1_000_000,
|
|
17
|
+
)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from lm_deluge import LLMClient
|
|
2
|
+
|
|
3
|
+
mixture_of_llamas = LLMClient(
|
|
4
|
+
["llama-4-scout", "llama-4-maverick", "llama-3.3-70b", "llama-3.3-8b"],
|
|
5
|
+
max_requests_per_minute=12_000,
|
|
6
|
+
max_tokens_per_minute=4_000_000,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
multimodal_llamas = LLMClient(
|
|
10
|
+
["llama-4-scout", "llama-4-maverick"],
|
|
11
|
+
max_requests_per_minute=6_000,
|
|
12
|
+
max_tokens_per_minute=2_000_000,
|
|
13
|
+
)
|
|
@@ -333,6 +333,23 @@ class Message:
|
|
|
333
333
|
"""
|
|
334
334
|
Return a JSON-serialisable dict that fully captures the message.
|
|
335
335
|
"""
|
|
336
|
+
def _json_safe(value):
|
|
337
|
+
if isinstance(value, (str, int, float, bool)) or value is None:
|
|
338
|
+
return value
|
|
339
|
+
if isinstance(value, list):
|
|
340
|
+
return [_json_safe(v) for v in value]
|
|
341
|
+
if isinstance(value, dict):
|
|
342
|
+
return {k: _json_safe(v) for k, v in value.items()}
|
|
343
|
+
if isinstance(value, Text):
|
|
344
|
+
return {"type": "text", "text": value.text}
|
|
345
|
+
if isinstance(value, Image):
|
|
346
|
+
w, h = value.size
|
|
347
|
+
return {"type": "image", "tag": f"<Image ({w}×{h})>"}
|
|
348
|
+
if isinstance(value, File):
|
|
349
|
+
size = value.size
|
|
350
|
+
return {"type": "file", "tag": f"<File ({size} bytes)>"}
|
|
351
|
+
return repr(value)
|
|
352
|
+
|
|
336
353
|
content_blocks: list[dict] = []
|
|
337
354
|
for p in self.parts:
|
|
338
355
|
if isinstance(p, Text):
|
|
@@ -349,7 +366,7 @@ class Message:
|
|
|
349
366
|
"type": "tool_call",
|
|
350
367
|
"id": p.id,
|
|
351
368
|
"name": p.name,
|
|
352
|
-
"arguments": p.arguments,
|
|
369
|
+
"arguments": _json_safe(p.arguments),
|
|
353
370
|
}
|
|
354
371
|
)
|
|
355
372
|
elif isinstance(p, ToolResult):
|
|
@@ -357,7 +374,7 @@ class Message:
|
|
|
357
374
|
{
|
|
358
375
|
"type": "tool_result",
|
|
359
376
|
"tool_call_id": p.tool_call_id,
|
|
360
|
-
"result": p.result,
|
|
377
|
+
"result": _json_safe(p.result),
|
|
361
378
|
}
|
|
362
379
|
)
|
|
363
380
|
elif isinstance(p, Thinking):
|
|
@@ -66,6 +66,8 @@ src/lm_deluge/models/mistral.py
|
|
|
66
66
|
src/lm_deluge/models/openai.py
|
|
67
67
|
src/lm_deluge/models/openrouter.py
|
|
68
68
|
src/lm_deluge/models/together.py
|
|
69
|
+
src/lm_deluge/presets/cerebras.py
|
|
70
|
+
src/lm_deluge/presets/meta.py
|
|
69
71
|
src/lm_deluge/util/harmony.py
|
|
70
72
|
src/lm_deluge/util/json.py
|
|
71
73
|
src/lm_deluge/util/logprobs.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{lm_deluge-0.0.44 → lm_deluge-0.0.46}/src/lm_deluge/built_in_tools/anthropic/computer_use.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|