lm-deluge 0.0.31__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.31/src/lm_deluge.egg-info → lm_deluge-0.0.32}/PKG-INFO +1 -1
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/pyproject.toml +1 -1
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/anthropic.py +2 -2
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/client.py +106 -14
- {lm_deluge-0.0.31 → lm_deluge-0.0.32/src/lm_deluge.egg-info}/PKG-INFO +1 -1
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/LICENSE +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/README.md +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/setup.cfg +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/__init__.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/agent.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/__init__.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/base.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/bedrock.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/common.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/deprecated/bedrock.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/deprecated/cohere.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/deprecated/deepseek.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/deprecated/mistral.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/deprecated/vertex.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/gemini.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/mistral.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/openai.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/api_requests/response.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/batches.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/built_in_tools/anthropic/__init__.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/built_in_tools/anthropic/bash.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/built_in_tools/anthropic/computer_use.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/built_in_tools/anthropic/editor.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/built_in_tools/base.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/built_in_tools/openai.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/cache.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/config.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/embed.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/errors.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/file.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/gemini_limits.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/image.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/llm_tools/__init__.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/llm_tools/classify.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/llm_tools/extract.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/llm_tools/locate.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/llm_tools/ocr.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/llm_tools/score.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/llm_tools/translate.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/models.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/prompt.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/request_context.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/rerank.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/tool.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/tracker.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/usage.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/util/json.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/util/logprobs.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/util/spatial.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/util/validation.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge/util/xml.py +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge.egg-info/SOURCES.txt +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge.egg-info/dependency_links.txt +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge.egg-info/requires.txt +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/src/lm_deluge.egg-info/top_level.txt +0 -0
- {lm_deluge-0.0.31 → lm_deluge-0.0.32}/tests/test_builtin_tools.py +0 -0
- {lm_deluge-0.0.31 → 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",
|
|
@@ -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,
|
|
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.31 → 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
|
|
File without changes
|
|
File without changes
|