lm-deluge 0.0.30__tar.gz → 0.0.32__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.30/src/lm_deluge.egg-info → lm_deluge-0.0.32}/PKG-INFO +1 -1
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/pyproject.toml +1 -1
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/anthropic.py +2 -2
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/bedrock.py +4 -1
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/client.py +106 -14
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/file.py +4 -1
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/models.py +1 -1
- {lm_deluge-0.0.30 → lm_deluge-0.0.32/src/lm_deluge.egg-info}/PKG-INFO +1 -1
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/LICENSE +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/README.md +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/setup.cfg +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/__init__.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/agent.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/__init__.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/base.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/common.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/deprecated/bedrock.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/deprecated/cohere.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/deprecated/deepseek.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/deprecated/mistral.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/deprecated/vertex.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/gemini.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/mistral.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/openai.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/response.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/batches.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/built_in_tools/anthropic/__init__.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/built_in_tools/anthropic/bash.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/built_in_tools/anthropic/computer_use.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/built_in_tools/anthropic/editor.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/built_in_tools/base.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/built_in_tools/openai.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/cache.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/config.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/embed.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/errors.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/gemini_limits.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/image.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/llm_tools/__init__.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/llm_tools/classify.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/llm_tools/extract.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/llm_tools/locate.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/llm_tools/ocr.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/llm_tools/score.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/llm_tools/translate.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/prompt.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/request_context.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/rerank.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/tool.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/tracker.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/usage.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/util/json.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/util/logprobs.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/util/spatial.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/util/validation.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge/util/xml.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge.egg-info/SOURCES.txt +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge.egg-info/dependency_links.txt +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge.egg-info/requires.txt +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/src/lm_deluge.egg-info/top_level.txt +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/tests/test_builtin_tools.py +0 -0
- {lm_deluge-0.0.30 → lm_deluge-0.0.32}/tests/test_native_mcp_server.py +0 -0
|
@@ -38,8 +38,8 @@ def _build_anthropic_request(
|
|
|
38
38
|
tools = context.tools
|
|
39
39
|
sampling_params = context.sampling_params
|
|
40
40
|
system_message, messages = prompt.to_anthropic(cache_pattern=cache_pattern)
|
|
41
|
-
if not system_message:
|
|
42
|
-
|
|
41
|
+
# if not system_message:
|
|
42
|
+
# print("WARNING: system_message is None")
|
|
43
43
|
base_headers = {
|
|
44
44
|
"x-api-key": os.getenv(model.api_key_env_var),
|
|
45
45
|
"anthropic-version": "2023-06-01",
|
|
@@ -132,7 +132,7 @@ async def _build_anthropic_bedrock_request(
|
|
|
132
132
|
if len(mcp_servers) > 0:
|
|
133
133
|
request_json["mcp_servers"] = mcp_servers
|
|
134
134
|
|
|
135
|
-
return request_json, base_headers, auth, url
|
|
135
|
+
return request_json, base_headers, auth, url, region
|
|
136
136
|
|
|
137
137
|
|
|
138
138
|
class BedrockRequest(APIRequestBase):
|
|
@@ -140,6 +140,7 @@ class BedrockRequest(APIRequestBase):
|
|
|
140
140
|
super().__init__(context=context)
|
|
141
141
|
|
|
142
142
|
self.model = APIModel.from_registry(self.context.model_name)
|
|
143
|
+
self.region = None # Will be set during build_request
|
|
143
144
|
|
|
144
145
|
async def build_request(self):
|
|
145
146
|
self.url = f"{self.model.api_base}/messages"
|
|
@@ -153,6 +154,7 @@ class BedrockRequest(APIRequestBase):
|
|
|
153
154
|
base_headers,
|
|
154
155
|
self.auth,
|
|
155
156
|
self.url,
|
|
157
|
+
self.region,
|
|
156
158
|
) = await _build_anthropic_bedrock_request(self.model, self.context)
|
|
157
159
|
self.request_header = self.merge_headers(
|
|
158
160
|
base_headers, exclude_patterns=["anthropic", "openai", "gemini", "mistral"]
|
|
@@ -160,6 +162,7 @@ class BedrockRequest(APIRequestBase):
|
|
|
160
162
|
|
|
161
163
|
async def execute_once(self) -> APIResponse:
|
|
162
164
|
"""Override execute_once to handle AWS4Auth signing."""
|
|
165
|
+
await self.build_request()
|
|
163
166
|
import aiohttp
|
|
164
167
|
|
|
165
168
|
assert self.context.status_tracker
|
|
@@ -4,7 +4,7 @@ from typing import Any, Literal, Self, Sequence, overload
|
|
|
4
4
|
|
|
5
5
|
import numpy as np
|
|
6
6
|
import yaml
|
|
7
|
-
from pydantic import BaseModel
|
|
7
|
+
from pydantic import BaseModel, PrivateAttr
|
|
8
8
|
from pydantic.functional_validators import model_validator
|
|
9
9
|
|
|
10
10
|
from lm_deluge.api_requests.openai import stream_chat
|
|
@@ -32,13 +32,7 @@ class LLMClient(BaseModel):
|
|
|
32
32
|
Handles models, sampling params for each model, model weights, rate limits, etc.
|
|
33
33
|
"""
|
|
34
34
|
|
|
35
|
-
model_names: list[str] = ["gpt-4.1-mini"]
|
|
36
|
-
|
|
37
|
-
def __init__(self, model_name: str | list[str] | None = None, **kwargs):
|
|
38
|
-
if model_name is not None:
|
|
39
|
-
kwargs["model_names"] = model_name
|
|
40
|
-
super().__init__(**kwargs)
|
|
41
|
-
|
|
35
|
+
model_names: str | list[str] = ["gpt-4.1-mini"]
|
|
42
36
|
max_requests_per_minute: int = 1_000
|
|
43
37
|
max_tokens_per_minute: int = 100_000
|
|
44
38
|
max_concurrent_requests: int = 225
|
|
@@ -59,6 +53,13 @@ class LLMClient(BaseModel):
|
|
|
59
53
|
top_logprobs: int | None = None
|
|
60
54
|
force_local_mcp: bool = False
|
|
61
55
|
|
|
56
|
+
# Internal state for async task handling
|
|
57
|
+
_next_task_id: int = PrivateAttr(default=0)
|
|
58
|
+
_tasks: dict[int, asyncio.Task] = PrivateAttr(default_factory=dict)
|
|
59
|
+
_results: dict[int, APIResponse] = PrivateAttr(default_factory=dict)
|
|
60
|
+
_tracker: StatusTracker | None = PrivateAttr(default=None)
|
|
61
|
+
_capacity_lock: asyncio.Lock = PrivateAttr(default_factory=asyncio.Lock)
|
|
62
|
+
|
|
62
63
|
# NEW! Builder methods
|
|
63
64
|
def with_model(self, model: str):
|
|
64
65
|
self.model_names = [model]
|
|
@@ -81,6 +82,18 @@ class LLMClient(BaseModel):
|
|
|
81
82
|
if max_concurrent_requests:
|
|
82
83
|
self.max_concurrent_requests = max_concurrent_requests
|
|
83
84
|
|
|
85
|
+
def _get_tracker(self) -> StatusTracker:
|
|
86
|
+
if self._tracker is None:
|
|
87
|
+
self._tracker = StatusTracker(
|
|
88
|
+
max_requests_per_minute=self.max_requests_per_minute,
|
|
89
|
+
max_tokens_per_minute=self.max_tokens_per_minute,
|
|
90
|
+
max_concurrent_requests=self.max_concurrent_requests,
|
|
91
|
+
use_progress_bar=False,
|
|
92
|
+
progress_bar_disable=True,
|
|
93
|
+
use_rich=False,
|
|
94
|
+
)
|
|
95
|
+
return self._tracker
|
|
96
|
+
|
|
84
97
|
@property
|
|
85
98
|
def models(self):
|
|
86
99
|
return self.model_names # why? idk
|
|
@@ -90,6 +103,8 @@ class LLMClient(BaseModel):
|
|
|
90
103
|
def fix_lists(cls, data) -> "LLMClient":
|
|
91
104
|
if isinstance(data.get("model_names"), str):
|
|
92
105
|
data["model_names"] = [data["model_names"]]
|
|
106
|
+
if not isinstance(data.get("sampling_params", []), list):
|
|
107
|
+
data["sampling_params"] = [data["sampling_params"]]
|
|
93
108
|
if "sampling_params" not in data or len(data.get("sampling_params", [])) == 0:
|
|
94
109
|
data["sampling_params"] = [
|
|
95
110
|
SamplingParams(
|
|
@@ -192,14 +207,19 @@ class LLMClient(BaseModel):
|
|
|
192
207
|
chosen_sp = self.sampling_params[self.models.index(chosen_model)]
|
|
193
208
|
return chosen_model, chosen_sp
|
|
194
209
|
|
|
195
|
-
async def _wait_for_capacity(
|
|
210
|
+
async def _wait_for_capacity(
|
|
211
|
+
self, num_tokens: int, tracker: StatusTracker, *, retry: bool = False
|
|
212
|
+
):
|
|
196
213
|
while True:
|
|
197
|
-
|
|
198
|
-
tracker.
|
|
199
|
-
|
|
214
|
+
async with self._capacity_lock:
|
|
215
|
+
tracker.update_capacity()
|
|
216
|
+
if tracker.check_capacity(num_tokens, retry=retry):
|
|
217
|
+
tracker.set_limiting_factor(None)
|
|
218
|
+
return
|
|
219
|
+
seconds_to_pause = tracker.seconds_to_pause
|
|
200
220
|
|
|
201
|
-
if
|
|
202
|
-
await asyncio.sleep(
|
|
221
|
+
if seconds_to_pause > 0:
|
|
222
|
+
await asyncio.sleep(seconds_to_pause)
|
|
203
223
|
else:
|
|
204
224
|
await asyncio.sleep(random.random())
|
|
205
225
|
|
|
@@ -446,6 +466,78 @@ class LLMClient(BaseModel):
|
|
|
446
466
|
)
|
|
447
467
|
)
|
|
448
468
|
|
|
469
|
+
async def _run_context(self, context: RequestContext) -> APIResponse:
|
|
470
|
+
tracker = self._get_tracker()
|
|
471
|
+
retry = False
|
|
472
|
+
retry_queue: asyncio.Queue[RequestContext] = asyncio.Queue()
|
|
473
|
+
current = context
|
|
474
|
+
while True:
|
|
475
|
+
await self._wait_for_capacity(current.num_tokens, tracker, retry=retry)
|
|
476
|
+
response = await self.process_single_request(current, retry_queue)
|
|
477
|
+
if not response.is_error or retry_queue.empty():
|
|
478
|
+
self._results[context.task_id] = response
|
|
479
|
+
return response
|
|
480
|
+
current = await retry_queue.get()
|
|
481
|
+
retry = True
|
|
482
|
+
|
|
483
|
+
def start_nowait(
|
|
484
|
+
self,
|
|
485
|
+
prompt: str | Conversation,
|
|
486
|
+
*,
|
|
487
|
+
tools: list[Tool | dict | MCPServer] | None = None,
|
|
488
|
+
cache: CachePattern | None = None,
|
|
489
|
+
use_responses_api: bool = False,
|
|
490
|
+
) -> int:
|
|
491
|
+
tracker = self._get_tracker()
|
|
492
|
+
task_id = self._next_task_id
|
|
493
|
+
self._next_task_id += 1
|
|
494
|
+
model, sampling_params = self._select_model()
|
|
495
|
+
if isinstance(prompt, str):
|
|
496
|
+
prompt = Conversation.user(prompt)
|
|
497
|
+
context = RequestContext(
|
|
498
|
+
task_id=task_id,
|
|
499
|
+
model_name=model,
|
|
500
|
+
prompt=prompt,
|
|
501
|
+
sampling_params=sampling_params,
|
|
502
|
+
attempts_left=self.max_attempts,
|
|
503
|
+
request_timeout=self.request_timeout,
|
|
504
|
+
status_tracker=tracker,
|
|
505
|
+
tools=tools,
|
|
506
|
+
cache=cache,
|
|
507
|
+
use_responses_api=use_responses_api,
|
|
508
|
+
extra_headers=self.extra_headers,
|
|
509
|
+
force_local_mcp=self.force_local_mcp,
|
|
510
|
+
)
|
|
511
|
+
task = asyncio.create_task(self._run_context(context))
|
|
512
|
+
self._tasks[task_id] = task
|
|
513
|
+
return task_id
|
|
514
|
+
|
|
515
|
+
async def start(
|
|
516
|
+
self,
|
|
517
|
+
prompt: str | Conversation,
|
|
518
|
+
*,
|
|
519
|
+
tools: list[Tool | dict | MCPServer] | None = None,
|
|
520
|
+
cache: CachePattern | None = None,
|
|
521
|
+
use_responses_api: bool = False,
|
|
522
|
+
) -> APIResponse | None:
|
|
523
|
+
task_id = self.start_nowait(
|
|
524
|
+
prompt, tools=tools, cache=cache, use_responses_api=use_responses_api
|
|
525
|
+
)
|
|
526
|
+
return await self.wait_for(task_id)
|
|
527
|
+
|
|
528
|
+
async def wait_for(self, task_id: int) -> APIResponse | None:
|
|
529
|
+
task = self._tasks.get(task_id)
|
|
530
|
+
if task:
|
|
531
|
+
return await task
|
|
532
|
+
return self._results.get(task_id)
|
|
533
|
+
|
|
534
|
+
async def wait_for_all(
|
|
535
|
+
self, task_ids: Sequence[int] | None = None
|
|
536
|
+
) -> list[APIResponse | None]:
|
|
537
|
+
if task_ids is None:
|
|
538
|
+
task_ids = list(self._tasks.keys())
|
|
539
|
+
return [await self.wait_for(tid) for tid in task_ids]
|
|
540
|
+
|
|
449
541
|
async def stream(
|
|
450
542
|
self,
|
|
451
543
|
prompt: str | Conversation,
|
|
@@ -37,7 +37,10 @@ class File:
|
|
|
37
37
|
header, encoded = self.data.split(",", 1)
|
|
38
38
|
return base64.b64decode(encoded)
|
|
39
39
|
else:
|
|
40
|
-
|
|
40
|
+
err = f"unreadable file. self.data type: {type(self.data)}"
|
|
41
|
+
if isinstance(self.data, str) and len(self.data) < 1_000:
|
|
42
|
+
err += f". self.data: {len(self.data)}"
|
|
43
|
+
raise ValueError(err)
|
|
41
44
|
|
|
42
45
|
def _mime(self) -> str:
|
|
43
46
|
if self.media_type:
|
|
@@ -28,7 +28,7 @@ BUILTIN_MODELS = {
|
|
|
28
28
|
"reasoning_model": False,
|
|
29
29
|
},
|
|
30
30
|
"llama-4-maverick": {
|
|
31
|
-
"id": "llama-4-
|
|
31
|
+
"id": "llama-4-maverick",
|
|
32
32
|
"name": "Llama-4-Maverick-17B-128E-Instruct-FP8",
|
|
33
33
|
"api_base": "https://api.llama.com/compat/v1",
|
|
34
34
|
"api_key_env_var": "META_API_KEY",
|
|
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.30 → lm_deluge-0.0.32}/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
|