blaxel 0.2.37__py3-none-any.whl → 0.2.38rc122__py3-none-any.whl
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.
- blaxel/__init__.py +2 -2
- blaxel/llamaindex/model.py +119 -74
- {blaxel-0.2.37.dist-info → blaxel-0.2.38rc122.dist-info}/METADATA +1 -1
- {blaxel-0.2.37.dist-info → blaxel-0.2.38rc122.dist-info}/RECORD +6 -6
- {blaxel-0.2.37.dist-info → blaxel-0.2.38rc122.dist-info}/WHEEL +0 -0
- {blaxel-0.2.37.dist-info → blaxel-0.2.38rc122.dist-info}/licenses/LICENSE +0 -0
blaxel/__init__.py
CHANGED
|
@@ -4,8 +4,8 @@ from .core.common.autoload import autoload
|
|
|
4
4
|
from .core.common.env import env
|
|
5
5
|
from .core.common.settings import settings
|
|
6
6
|
|
|
7
|
-
__version__ = "0.2.
|
|
8
|
-
__commit__ = "
|
|
7
|
+
__version__ = "0.2.38.pre-122"
|
|
8
|
+
__commit__ = "e7e19d2c82b2b0c2a44914245734597adcc00f49"
|
|
9
9
|
__sentry_dsn__ = "https://9711de13cd02b285ca4378c01de8dc30@o4508714045276160.ingest.us.sentry.io/4510461121462272"
|
|
10
10
|
__all__ = ["autoload", "settings", "env"]
|
|
11
11
|
|
blaxel/llamaindex/model.py
CHANGED
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
4
|
from logging import getLogger
|
|
5
|
-
from typing import TYPE_CHECKING, Any, Sequence
|
|
5
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Sequence, Union
|
|
6
6
|
|
|
7
7
|
from blaxel.core import bl_model as bl_model_core
|
|
8
8
|
from blaxel.core import settings
|
|
@@ -20,20 +20,61 @@ if TYPE_CHECKING:
|
|
|
20
20
|
CompletionResponseAsyncGen,
|
|
21
21
|
CompletionResponseGen,
|
|
22
22
|
)
|
|
23
|
+
from llama_index.core.llms.llm import ToolSelection
|
|
24
|
+
from llama_index.core.tools.types import BaseTool
|
|
25
|
+
|
|
26
|
+
# Runtime imports needed for class inheritance and construction
|
|
27
|
+
from llama_index.core.base.llms.types import LLMMetadata # noqa: E402
|
|
28
|
+
from llama_index.core.llms.function_calling import FunctionCallingLLM # noqa: E402
|
|
29
|
+
from pydantic import PrivateAttr # noqa: E402
|
|
23
30
|
|
|
24
31
|
logger = getLogger(__name__)
|
|
25
32
|
|
|
33
|
+
DEFAULT_CONTEXT_WINDOW = 128000
|
|
34
|
+
DEFAULT_NUM_OUTPUT = 4096
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class TokenRefreshingLLM(FunctionCallingLLM):
|
|
38
|
+
"""Wrapper for LlamaIndex LLMs that refreshes token before each call.
|
|
26
39
|
|
|
27
|
-
|
|
28
|
-
|
|
40
|
+
Inherits from FunctionCallingLLM to maintain type compatibility with
|
|
41
|
+
LlamaIndex's agents and components that validate isinstance(model, LLM).
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
_model_config_data: dict = PrivateAttr(default_factory=dict)
|
|
45
|
+
_wrapped: Any = PrivateAttr(default=None)
|
|
29
46
|
|
|
30
47
|
def __init__(self, model_config: dict):
|
|
31
|
-
|
|
32
|
-
self.
|
|
48
|
+
super().__init__()
|
|
49
|
+
self._model_config_data = model_config
|
|
50
|
+
self._wrapped = self._create_model()
|
|
51
|
+
|
|
52
|
+
@classmethod
|
|
53
|
+
def class_name(cls) -> str:
|
|
54
|
+
return "TokenRefreshingLLM"
|
|
55
|
+
|
|
56
|
+
@property
|
|
57
|
+
def wrapped_model(self) -> Any:
|
|
58
|
+
"""Access the underlying wrapped LLM model."""
|
|
59
|
+
return self._wrapped
|
|
60
|
+
|
|
61
|
+
@property
|
|
62
|
+
def metadata(self) -> LLMMetadata:
|
|
63
|
+
"""Get LLM metadata, with fallback for unknown model names."""
|
|
64
|
+
try:
|
|
65
|
+
return self._wrapped.metadata
|
|
66
|
+
except (ValueError, KeyError) as e:
|
|
67
|
+
logger.warning(f"Could not get metadata from wrapped model: {e}. Using defaults.")
|
|
68
|
+
return LLMMetadata(
|
|
69
|
+
context_window=DEFAULT_CONTEXT_WINDOW,
|
|
70
|
+
num_output=DEFAULT_NUM_OUTPUT,
|
|
71
|
+
is_chat_model=True,
|
|
72
|
+
model_name=self._model_config_data.get("model", "unknown"),
|
|
73
|
+
)
|
|
33
74
|
|
|
34
75
|
def _create_model(self):
|
|
35
76
|
"""Create the model instance with current token."""
|
|
36
|
-
config = self.
|
|
77
|
+
config = self._model_config_data
|
|
37
78
|
model_type = config["type"]
|
|
38
79
|
model = config["model"]
|
|
39
80
|
url = config["url"]
|
|
@@ -115,102 +156,106 @@ class TokenRefreshingWrapper:
|
|
|
115
156
|
|
|
116
157
|
def _refresh_token(self):
|
|
117
158
|
"""Refresh the token and recreate the model if needed."""
|
|
118
|
-
# Only refresh if using ClientCredentials (which has get_token method)
|
|
119
159
|
current_token = settings.auth.token
|
|
120
160
|
|
|
121
|
-
if hasattr(settings.auth, "get_token"):
|
|
122
|
-
# This will trigger token refresh if needed
|
|
123
|
-
settings.auth.get_token()
|
|
124
|
-
|
|
125
161
|
new_token = settings.auth.token
|
|
126
162
|
|
|
127
|
-
# If token changed, recreate the model
|
|
128
163
|
if current_token != new_token:
|
|
129
|
-
self.
|
|
164
|
+
self._wrapped = self._create_model()
|
|
130
165
|
|
|
131
|
-
|
|
132
|
-
"""Delegate attribute access to wrapped model."""
|
|
133
|
-
return getattr(self.wrapped_model, name)
|
|
166
|
+
# --- Core LLM methods with token refresh ---
|
|
134
167
|
|
|
168
|
+
def chat(self, messages: Sequence[ChatMessage], **kwargs: Any) -> ChatResponse:
|
|
169
|
+
self._refresh_token()
|
|
170
|
+
return self._wrapped.chat(messages, **kwargs)
|
|
135
171
|
|
|
136
|
-
|
|
137
|
-
"""Wrapper for LlamaIndex LLMs that refreshes token before each call."""
|
|
138
|
-
|
|
139
|
-
async def achat(
|
|
140
|
-
self,
|
|
141
|
-
messages: Sequence[ChatMessage],
|
|
142
|
-
**kwargs: Any,
|
|
143
|
-
) -> ChatResponse:
|
|
144
|
-
"""Async chat with token refresh."""
|
|
172
|
+
async def achat(self, messages: Sequence[ChatMessage], **kwargs: Any) -> ChatResponse:
|
|
145
173
|
self._refresh_token()
|
|
146
|
-
return await self.
|
|
174
|
+
return await self._wrapped.achat(messages, **kwargs)
|
|
147
175
|
|
|
148
|
-
def
|
|
149
|
-
self,
|
|
150
|
-
messages: Sequence[ChatMessage],
|
|
151
|
-
**kwargs: Any,
|
|
152
|
-
) -> ChatResponse:
|
|
153
|
-
"""Sync chat with token refresh."""
|
|
176
|
+
def complete(self, prompt: str, formatted: bool = False, **kwargs: Any) -> CompletionResponse:
|
|
154
177
|
self._refresh_token()
|
|
155
|
-
return self.
|
|
178
|
+
return self._wrapped.complete(prompt, formatted=formatted, **kwargs)
|
|
156
179
|
|
|
157
|
-
async def
|
|
158
|
-
self,
|
|
159
|
-
|
|
160
|
-
**kwargs: Any,
|
|
161
|
-
) -> ChatResponseAsyncGen:
|
|
162
|
-
"""Async stream chat with token refresh."""
|
|
180
|
+
async def acomplete(
|
|
181
|
+
self, prompt: str, formatted: bool = False, **kwargs: Any
|
|
182
|
+
) -> CompletionResponse:
|
|
163
183
|
self._refresh_token()
|
|
164
|
-
|
|
165
|
-
yield chunk
|
|
184
|
+
return await self._wrapped.acomplete(prompt, formatted=formatted, **kwargs)
|
|
166
185
|
|
|
167
186
|
def stream_chat(
|
|
168
|
-
self,
|
|
169
|
-
messages: Sequence[ChatMessage],
|
|
170
|
-
**kwargs: Any,
|
|
187
|
+
self, messages: Sequence[ChatMessage], **kwargs: Any
|
|
171
188
|
) -> ChatResponseGen:
|
|
172
|
-
"""Sync stream chat with token refresh."""
|
|
173
189
|
self._refresh_token()
|
|
174
|
-
|
|
175
|
-
yield chunk
|
|
190
|
+
return self._wrapped.stream_chat(messages, **kwargs)
|
|
176
191
|
|
|
177
|
-
async def
|
|
178
|
-
self,
|
|
179
|
-
|
|
180
|
-
**kwargs: Any,
|
|
181
|
-
) -> CompletionResponse:
|
|
182
|
-
"""Async complete with token refresh."""
|
|
192
|
+
async def astream_chat(
|
|
193
|
+
self, messages: Sequence[ChatMessage], **kwargs: Any
|
|
194
|
+
) -> ChatResponseAsyncGen:
|
|
183
195
|
self._refresh_token()
|
|
184
|
-
|
|
196
|
+
result = self._wrapped.astream_chat(messages, **kwargs)
|
|
197
|
+
# Handle both coroutine and async generator patterns
|
|
198
|
+
if hasattr(result, "__aiter__"):
|
|
199
|
+
return result
|
|
200
|
+
return await result
|
|
185
201
|
|
|
186
|
-
def
|
|
187
|
-
self,
|
|
188
|
-
|
|
189
|
-
**kwargs: Any,
|
|
190
|
-
) -> CompletionResponse:
|
|
191
|
-
"""Sync complete with token refresh."""
|
|
202
|
+
def stream_complete(
|
|
203
|
+
self, prompt: str, formatted: bool = False, **kwargs: Any
|
|
204
|
+
) -> CompletionResponseGen:
|
|
192
205
|
self._refresh_token()
|
|
193
|
-
return self.
|
|
206
|
+
return self._wrapped.stream_complete(prompt, formatted=formatted, **kwargs)
|
|
194
207
|
|
|
195
208
|
async def astream_complete(
|
|
196
|
-
self,
|
|
197
|
-
prompt: str,
|
|
198
|
-
**kwargs: Any,
|
|
209
|
+
self, prompt: str, formatted: bool = False, **kwargs: Any
|
|
199
210
|
) -> CompletionResponseAsyncGen:
|
|
200
|
-
"""Async stream complete with token refresh."""
|
|
201
211
|
self._refresh_token()
|
|
202
|
-
|
|
203
|
-
|
|
212
|
+
result = self._wrapped.astream_complete(prompt, formatted=formatted, **kwargs)
|
|
213
|
+
# Handle both coroutine and async generator patterns
|
|
214
|
+
if hasattr(result, "__aiter__"):
|
|
215
|
+
return result
|
|
216
|
+
return await result
|
|
204
217
|
|
|
205
|
-
|
|
218
|
+
# --- FunctionCallingLLM methods (delegate to wrapped model) ---
|
|
219
|
+
|
|
220
|
+
def _prepare_chat_with_tools(
|
|
206
221
|
self,
|
|
207
|
-
|
|
222
|
+
tools: Sequence[BaseTool],
|
|
223
|
+
user_msg: Union[str, ChatMessage, None] = None,
|
|
224
|
+
chat_history: List[ChatMessage] | None = None,
|
|
225
|
+
verbose: bool = False,
|
|
226
|
+
allow_parallel_tool_calls: bool = False,
|
|
227
|
+
tool_required: Any = None,
|
|
208
228
|
**kwargs: Any,
|
|
209
|
-
) ->
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
229
|
+
) -> Dict[str, Any]:
|
|
230
|
+
if hasattr(self._wrapped, "_prepare_chat_with_tools"):
|
|
231
|
+
return self._wrapped._prepare_chat_with_tools(
|
|
232
|
+
tools,
|
|
233
|
+
user_msg=user_msg,
|
|
234
|
+
chat_history=chat_history,
|
|
235
|
+
verbose=verbose,
|
|
236
|
+
allow_parallel_tool_calls=allow_parallel_tool_calls,
|
|
237
|
+
tool_required=tool_required,
|
|
238
|
+
**kwargs,
|
|
239
|
+
)
|
|
240
|
+
raise NotImplementedError(
|
|
241
|
+
f"The wrapped model ({type(self._wrapped).__name__}) does not support function calling"
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
def get_tool_calls_from_response(
|
|
245
|
+
self,
|
|
246
|
+
response: ChatResponse,
|
|
247
|
+
error_on_no_tool_call: bool = True,
|
|
248
|
+
**kwargs: Any,
|
|
249
|
+
) -> List[ToolSelection]:
|
|
250
|
+
if hasattr(self._wrapped, "get_tool_calls_from_response"):
|
|
251
|
+
return self._wrapped.get_tool_calls_from_response(
|
|
252
|
+
response,
|
|
253
|
+
error_on_no_tool_call=error_on_no_tool_call,
|
|
254
|
+
**kwargs,
|
|
255
|
+
)
|
|
256
|
+
raise NotImplementedError(
|
|
257
|
+
f"The wrapped model ({type(self._wrapped).__name__}) does not support function calling"
|
|
258
|
+
)
|
|
214
259
|
|
|
215
260
|
|
|
216
261
|
async def bl_model(name, **kwargs):
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
blaxel/__init__.py,sha256=
|
|
1
|
+
blaxel/__init__.py,sha256=CJtHkLCfIuSmNEqG5afzbxuceMG5h0ve2VADXBGizWs,421
|
|
2
2
|
blaxel/core/__init__.py,sha256=CU0gXpVRbuQZNWoCJuuhZS0ZhXPEu0cg-3XzoYMrBm4,1756
|
|
3
3
|
blaxel/core/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
blaxel/core/agents/__init__.py,sha256=MJZga99lU8JWUUPHd4rmUfdo7ALwWgF7CQq95SfT2OI,4456
|
|
@@ -446,7 +446,7 @@ blaxel/livekit/model.py,sha256=Qhl3EVa4Uum1IsT3nyMxJwXrZn2eDvCyj6V8RHOaJsQ,1687
|
|
|
446
446
|
blaxel/livekit/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
447
447
|
blaxel/livekit/tools.py,sha256=QipxGDnKqma_ktzTUpKgzdp5x4bvpQnxEVoqSTBesu8,1053
|
|
448
448
|
blaxel/llamaindex/__init__.py,sha256=iZ3QbZhlwKvP91ChcqSXVkpRrzurMxJoQfKdZFzE2AA,127
|
|
449
|
-
blaxel/llamaindex/model.py,sha256=
|
|
449
|
+
blaxel/llamaindex/model.py,sha256=wDWEXn2oLCjdsJ9aBN6po6-LuiSuYa3-V6SRxBMTKG0,9405
|
|
450
450
|
blaxel/llamaindex/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
451
451
|
blaxel/llamaindex/tools.py,sha256=5wnPX45sgLduk9fPkhQ0rHRGK3Ekrye0MJNtMdw3GII,1024
|
|
452
452
|
blaxel/llamaindex/custom/cohere.py,sha256=8Kfo5BjrND6EFDZXosHNrgrg98ktvxhYG48ztaWptps,18707
|
|
@@ -472,7 +472,7 @@ blaxel/telemetry/instrumentation/map.py,sha256=PCzZJj39yiYVYJrxLBNP-NW-tjjYyTijw
|
|
|
472
472
|
blaxel/telemetry/instrumentation/utils.py,sha256=FGyMY5ZE4f-0JdZpm_R_BCoKLJ18hftz8vsh7ftDwMk,1889
|
|
473
473
|
blaxel/telemetry/log/log.py,sha256=vtzUIFIIj4MTTKUigILDYXN8NHHPOo44OaKukpyIjQg,2407
|
|
474
474
|
blaxel/telemetry/log/logger.py,sha256=IcFWCd1yyWWGAjAd2i0pDYqpZHQ61pmcaQ7Kf4bC8lg,4150
|
|
475
|
-
blaxel-0.2.
|
|
476
|
-
blaxel-0.2.
|
|
477
|
-
blaxel-0.2.
|
|
478
|
-
blaxel-0.2.
|
|
475
|
+
blaxel-0.2.38rc122.dist-info/METADATA,sha256=--Hscbw_W5MLB8BsePm4W1NIyMklqQuO-jdV0EBoI1E,18689
|
|
476
|
+
blaxel-0.2.38rc122.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
477
|
+
blaxel-0.2.38rc122.dist-info/licenses/LICENSE,sha256=p5PNQvpvyDT_0aYBDgmV1fFI_vAD2aSV0wWG7VTgRis,1069
|
|
478
|
+
blaxel-0.2.38rc122.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|