hammad-python 0.0.29__py3-none-any.whl → 0.0.31__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.
- ham/__init__.py +10 -0
- {hammad_python-0.0.29.dist-info → hammad_python-0.0.31.dist-info}/METADATA +6 -32
- hammad_python-0.0.31.dist-info/RECORD +6 -0
- hammad/__init__.py +0 -84
- hammad/_internal.py +0 -256
- hammad/_main.py +0 -226
- hammad/cache/__init__.py +0 -40
- hammad/cache/base_cache.py +0 -181
- hammad/cache/cache.py +0 -169
- hammad/cache/decorators.py +0 -261
- hammad/cache/file_cache.py +0 -80
- hammad/cache/ttl_cache.py +0 -74
- hammad/cli/__init__.py +0 -33
- hammad/cli/animations.py +0 -573
- hammad/cli/plugins.py +0 -867
- hammad/cli/styles/__init__.py +0 -55
- hammad/cli/styles/settings.py +0 -139
- hammad/cli/styles/types.py +0 -358
- hammad/cli/styles/utils.py +0 -634
- hammad/data/__init__.py +0 -90
- hammad/data/collections/__init__.py +0 -49
- hammad/data/collections/collection.py +0 -326
- hammad/data/collections/indexes/__init__.py +0 -37
- hammad/data/collections/indexes/qdrant/__init__.py +0 -1
- hammad/data/collections/indexes/qdrant/index.py +0 -723
- hammad/data/collections/indexes/qdrant/settings.py +0 -94
- hammad/data/collections/indexes/qdrant/utils.py +0 -210
- hammad/data/collections/indexes/tantivy/__init__.py +0 -1
- hammad/data/collections/indexes/tantivy/index.py +0 -426
- hammad/data/collections/indexes/tantivy/settings.py +0 -40
- hammad/data/collections/indexes/tantivy/utils.py +0 -176
- hammad/data/configurations/__init__.py +0 -35
- hammad/data/configurations/configuration.py +0 -564
- hammad/data/models/__init__.py +0 -50
- hammad/data/models/extensions/__init__.py +0 -4
- hammad/data/models/extensions/pydantic/__init__.py +0 -42
- hammad/data/models/extensions/pydantic/converters.py +0 -759
- hammad/data/models/fields.py +0 -546
- hammad/data/models/model.py +0 -1078
- hammad/data/models/utils.py +0 -280
- hammad/data/sql/__init__.py +0 -24
- hammad/data/sql/database.py +0 -576
- hammad/data/sql/types.py +0 -127
- hammad/data/types/__init__.py +0 -75
- hammad/data/types/file.py +0 -431
- hammad/data/types/multimodal/__init__.py +0 -36
- hammad/data/types/multimodal/audio.py +0 -200
- hammad/data/types/multimodal/image.py +0 -182
- hammad/data/types/text.py +0 -1308
- hammad/formatting/__init__.py +0 -33
- hammad/formatting/json/__init__.py +0 -27
- hammad/formatting/json/converters.py +0 -158
- hammad/formatting/text/__init__.py +0 -63
- hammad/formatting/text/converters.py +0 -723
- hammad/formatting/text/markdown.py +0 -131
- hammad/formatting/yaml/__init__.py +0 -26
- hammad/formatting/yaml/converters.py +0 -5
- hammad/genai/__init__.py +0 -217
- hammad/genai/a2a/__init__.py +0 -32
- hammad/genai/a2a/workers.py +0 -552
- hammad/genai/agents/__init__.py +0 -59
- hammad/genai/agents/agent.py +0 -1973
- hammad/genai/agents/run.py +0 -1024
- hammad/genai/agents/types/__init__.py +0 -42
- hammad/genai/agents/types/agent_context.py +0 -13
- hammad/genai/agents/types/agent_event.py +0 -128
- hammad/genai/agents/types/agent_hooks.py +0 -220
- hammad/genai/agents/types/agent_messages.py +0 -31
- hammad/genai/agents/types/agent_response.py +0 -125
- hammad/genai/agents/types/agent_stream.py +0 -327
- hammad/genai/graphs/__init__.py +0 -125
- hammad/genai/graphs/_utils.py +0 -190
- hammad/genai/graphs/base.py +0 -1828
- hammad/genai/graphs/plugins.py +0 -316
- hammad/genai/graphs/types.py +0 -638
- hammad/genai/models/__init__.py +0 -1
- hammad/genai/models/embeddings/__init__.py +0 -43
- hammad/genai/models/embeddings/model.py +0 -226
- hammad/genai/models/embeddings/run.py +0 -163
- hammad/genai/models/embeddings/types/__init__.py +0 -37
- hammad/genai/models/embeddings/types/embedding_model_name.py +0 -75
- hammad/genai/models/embeddings/types/embedding_model_response.py +0 -76
- hammad/genai/models/embeddings/types/embedding_model_run_params.py +0 -66
- hammad/genai/models/embeddings/types/embedding_model_settings.py +0 -47
- hammad/genai/models/language/__init__.py +0 -57
- hammad/genai/models/language/model.py +0 -1098
- hammad/genai/models/language/run.py +0 -878
- hammad/genai/models/language/types/__init__.py +0 -40
- hammad/genai/models/language/types/language_model_instructor_mode.py +0 -47
- hammad/genai/models/language/types/language_model_messages.py +0 -28
- hammad/genai/models/language/types/language_model_name.py +0 -239
- hammad/genai/models/language/types/language_model_request.py +0 -127
- hammad/genai/models/language/types/language_model_response.py +0 -217
- hammad/genai/models/language/types/language_model_response_chunk.py +0 -56
- hammad/genai/models/language/types/language_model_settings.py +0 -89
- hammad/genai/models/language/types/language_model_stream.py +0 -600
- hammad/genai/models/language/utils/__init__.py +0 -28
- hammad/genai/models/language/utils/requests.py +0 -421
- hammad/genai/models/language/utils/structured_outputs.py +0 -135
- hammad/genai/models/model_provider.py +0 -4
- hammad/genai/models/multimodal.py +0 -47
- hammad/genai/models/reranking.py +0 -26
- hammad/genai/types/__init__.py +0 -1
- hammad/genai/types/base.py +0 -215
- hammad/genai/types/history.py +0 -290
- hammad/genai/types/tools.py +0 -507
- hammad/logging/__init__.py +0 -35
- hammad/logging/decorators.py +0 -834
- hammad/logging/logger.py +0 -1018
- hammad/mcp/__init__.py +0 -53
- hammad/mcp/client/__init__.py +0 -35
- hammad/mcp/client/client.py +0 -624
- hammad/mcp/client/client_service.py +0 -400
- hammad/mcp/client/settings.py +0 -178
- hammad/mcp/servers/__init__.py +0 -26
- hammad/mcp/servers/launcher.py +0 -1161
- hammad/runtime/__init__.py +0 -32
- hammad/runtime/decorators.py +0 -142
- hammad/runtime/run.py +0 -299
- hammad/service/__init__.py +0 -49
- hammad/service/create.py +0 -527
- hammad/service/decorators.py +0 -283
- hammad/types.py +0 -288
- hammad/typing/__init__.py +0 -435
- hammad/web/__init__.py +0 -43
- hammad/web/http/__init__.py +0 -1
- hammad/web/http/client.py +0 -944
- hammad/web/models.py +0 -275
- hammad/web/openapi/__init__.py +0 -1
- hammad/web/openapi/client.py +0 -740
- hammad/web/search/__init__.py +0 -1
- hammad/web/search/client.py +0 -1023
- hammad/web/utils.py +0 -472
- hammad_python-0.0.29.dist-info/RECORD +0 -135
- {hammad → ham}/py.typed +0 -0
- {hammad_python-0.0.29.dist-info → hammad_python-0.0.31.dist-info}/WHEEL +0 -0
- {hammad_python-0.0.29.dist-info → hammad_python-0.0.31.dist-info}/licenses/LICENSE +0 -0
@@ -1,1098 +0,0 @@
|
|
1
|
-
"""hammad.genai.language_models.language_model"""
|
2
|
-
|
3
|
-
from typing import (
|
4
|
-
Any,
|
5
|
-
Callable,
|
6
|
-
List,
|
7
|
-
TypeVar,
|
8
|
-
Generic,
|
9
|
-
Union,
|
10
|
-
Optional,
|
11
|
-
Type,
|
12
|
-
overload,
|
13
|
-
Dict,
|
14
|
-
TYPE_CHECKING,
|
15
|
-
)
|
16
|
-
import functools
|
17
|
-
import inspect
|
18
|
-
import asyncio
|
19
|
-
from typing_extensions import Literal
|
20
|
-
|
21
|
-
if TYPE_CHECKING:
|
22
|
-
from httpx import Timeout
|
23
|
-
|
24
|
-
from ....logging.logger import _get_internal_logger
|
25
|
-
from ..model_provider import litellm, instructor
|
26
|
-
|
27
|
-
from ...types.base import BaseGenAIModel
|
28
|
-
from .types.language_model_instructor_mode import LanguageModelInstructorMode
|
29
|
-
from .types.language_model_name import LanguageModelName
|
30
|
-
from .types.language_model_messages import LanguageModelMessages
|
31
|
-
from .types.language_model_response import LanguageModelResponse
|
32
|
-
from .types.language_model_settings import LanguageModelSettings
|
33
|
-
from .types.language_model_stream import LanguageModelStream
|
34
|
-
|
35
|
-
from .utils import (
|
36
|
-
parse_messages_input,
|
37
|
-
handle_completion_request_params,
|
38
|
-
handle_completion_response,
|
39
|
-
handle_structured_output_request_params,
|
40
|
-
prepare_response_model,
|
41
|
-
handle_structured_output_response,
|
42
|
-
format_tool_calls,
|
43
|
-
LanguageModelRequestBuilder,
|
44
|
-
)
|
45
|
-
|
46
|
-
__all__ = [
|
47
|
-
"LanguageModel",
|
48
|
-
"LanguageModelError",
|
49
|
-
"create_language_model",
|
50
|
-
]
|
51
|
-
|
52
|
-
T = TypeVar("T")
|
53
|
-
|
54
|
-
|
55
|
-
logger = _get_internal_logger(__name__)
|
56
|
-
|
57
|
-
|
58
|
-
class LanguageModelError(Exception):
|
59
|
-
"""Error raised when an error occurs during a language model operation."""
|
60
|
-
|
61
|
-
def __init__(self, message: str, *args: Any, **kwargs: Any):
|
62
|
-
super().__init__(message, *args, **kwargs)
|
63
|
-
self.message = message
|
64
|
-
self.args = args
|
65
|
-
self.kwargs = kwargs
|
66
|
-
|
67
|
-
|
68
|
-
class LanguageModel(BaseGenAIModel, Generic[T]):
|
69
|
-
"""
|
70
|
-
A Generative AI model that can be used to generate text, chat completions,
|
71
|
-
structured outputs, call tools and more.
|
72
|
-
"""
|
73
|
-
|
74
|
-
model: LanguageModelName | str = "openai/gpt-4o-mini"
|
75
|
-
"""The model to use for requests."""
|
76
|
-
|
77
|
-
type: Type[T] = str
|
78
|
-
"""The type of the output of the language model."""
|
79
|
-
|
80
|
-
instructions: Optional[str] = None
|
81
|
-
"""Instructions for the language model."""
|
82
|
-
|
83
|
-
base_url: Optional[str] = None
|
84
|
-
api_key: Optional[str] = None
|
85
|
-
api_version: Optional[str] = None
|
86
|
-
organization: Optional[str] = None
|
87
|
-
deployment_id: Optional[str] = None
|
88
|
-
model_list: Optional[List[Any]] = None
|
89
|
-
extra_headers: Optional[Dict[str, str]] = None
|
90
|
-
|
91
|
-
settings: LanguageModelSettings = LanguageModelSettings()
|
92
|
-
"""Settings for the language model."""
|
93
|
-
|
94
|
-
instructor_mode: LanguageModelInstructorMode = "tool_call"
|
95
|
-
"""Default instructor mode for structured outputs."""
|
96
|
-
|
97
|
-
def __init__(
|
98
|
-
self,
|
99
|
-
model: LanguageModelName = "openai/gpt-4o-mini",
|
100
|
-
base_url: Optional[str] = None,
|
101
|
-
api_key: Optional[str] = None,
|
102
|
-
instructor_mode: LanguageModelInstructorMode = "tool_call",
|
103
|
-
verbose: bool = False,
|
104
|
-
debug: bool = False,
|
105
|
-
**kwargs: Any,
|
106
|
-
):
|
107
|
-
"""Initialize the language model.
|
108
|
-
|
109
|
-
Args:
|
110
|
-
model: The model to use for requests
|
111
|
-
base_url: Custom base URL for the API
|
112
|
-
api_key: API key for authentication
|
113
|
-
instructor_mode: Default instructor mode for structured outputs
|
114
|
-
verbose: If True, set logger to INFO level for detailed output
|
115
|
-
debug: If True, set logger to DEBUG level for maximum verbosity
|
116
|
-
**kwargs: Additional arguments passed to BaseGenAIModel
|
117
|
-
"""
|
118
|
-
# Initialize BaseGenAIModel via super()
|
119
|
-
super().__init__(model=model, base_url=base_url, api_key=api_key, **kwargs)
|
120
|
-
|
121
|
-
# Initialize LanguageModel-specific attributes
|
122
|
-
self._instructor_client = None
|
123
|
-
self.verbose = verbose
|
124
|
-
self.debug = debug
|
125
|
-
|
126
|
-
# Set logger level based on verbose/debug flags
|
127
|
-
if debug:
|
128
|
-
logger.setLevel("DEBUG")
|
129
|
-
elif verbose:
|
130
|
-
logger.setLevel("INFO")
|
131
|
-
|
132
|
-
logger.info(f"Initialized LanguageModel w/ model: {self.model}")
|
133
|
-
logger.debug(f"LanguageModel settings: {self.settings}")
|
134
|
-
|
135
|
-
def _get_instructor_client(
|
136
|
-
self, mode: Optional[LanguageModelInstructorMode] = None
|
137
|
-
):
|
138
|
-
"""Get or create an instructor client with the specified mode."""
|
139
|
-
effective_mode = mode or self.instructor_mode
|
140
|
-
|
141
|
-
# Create a new client if mode changed or client doesn't exist
|
142
|
-
if (
|
143
|
-
self._instructor_client is None
|
144
|
-
or getattr(self._instructor_client, "_mode", None) != effective_mode
|
145
|
-
):
|
146
|
-
logger.debug(
|
147
|
-
f"Creating new instructor client for mode: {effective_mode} from old mode: {getattr(self._instructor_client, '_mode', None)}"
|
148
|
-
)
|
149
|
-
|
150
|
-
self._instructor_client = instructor.from_litellm(
|
151
|
-
completion=litellm.completion, mode=instructor.Mode(effective_mode)
|
152
|
-
)
|
153
|
-
self._instructor_client._mode = effective_mode
|
154
|
-
|
155
|
-
return self._instructor_client
|
156
|
-
|
157
|
-
def _get_async_instructor_client(
|
158
|
-
self, mode: Optional[LanguageModelInstructorMode] = None
|
159
|
-
):
|
160
|
-
"""Get or create an async instructor client with the specified mode."""
|
161
|
-
effective_mode = mode or self.instructor_mode
|
162
|
-
|
163
|
-
return instructor.from_litellm(
|
164
|
-
completion=litellm.acompletion, mode=instructor.Mode(effective_mode)
|
165
|
-
)
|
166
|
-
|
167
|
-
# Overloaded run methods for different return types
|
168
|
-
|
169
|
-
@overload
|
170
|
-
def run(
|
171
|
-
self,
|
172
|
-
messages: LanguageModelMessages,
|
173
|
-
instructions: Optional[str] = None,
|
174
|
-
*,
|
175
|
-
stream: Literal[False] = False,
|
176
|
-
model: Optional[LanguageModelName | str] = None,
|
177
|
-
base_url: Optional[str] = None,
|
178
|
-
api_key: Optional[str] = None,
|
179
|
-
mock_response: Optional[str] = None,
|
180
|
-
**kwargs: Any,
|
181
|
-
) -> LanguageModelResponse[str]: ...
|
182
|
-
|
183
|
-
@overload
|
184
|
-
def run(
|
185
|
-
self,
|
186
|
-
messages: LanguageModelMessages,
|
187
|
-
instructions: Optional[str] = None,
|
188
|
-
*,
|
189
|
-
stream: Literal[False] = False,
|
190
|
-
model: Optional[LanguageModelName | str] = None,
|
191
|
-
base_url: Optional[str] = None,
|
192
|
-
api_key: Optional[str] = None,
|
193
|
-
temperature: Optional[float] = None,
|
194
|
-
max_tokens: Optional[int] = None,
|
195
|
-
top_p: Optional[float] = None,
|
196
|
-
tools: Optional[List[Any]] = None,
|
197
|
-
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
198
|
-
timeout: Optional[Union[float, str, "Timeout"]] = None,
|
199
|
-
presence_penalty: Optional[float] = None,
|
200
|
-
frequency_penalty: Optional[float] = None,
|
201
|
-
seed: Optional[int] = None,
|
202
|
-
user: Optional[str] = None,
|
203
|
-
mock_response: Optional[str] = None,
|
204
|
-
**kwargs: Any,
|
205
|
-
) -> LanguageModelResponse[str]: ...
|
206
|
-
|
207
|
-
@overload
|
208
|
-
def run(
|
209
|
-
self,
|
210
|
-
messages: LanguageModelMessages,
|
211
|
-
instructions: Optional[str] = None,
|
212
|
-
*,
|
213
|
-
stream: Literal[True],
|
214
|
-
model: Optional[LanguageModelName | str] = None,
|
215
|
-
base_url: Optional[str] = None,
|
216
|
-
api_key: Optional[str] = None,
|
217
|
-
mock_response: Optional[str] = None,
|
218
|
-
**kwargs: Any,
|
219
|
-
) -> LanguageModelStream[str]: ...
|
220
|
-
|
221
|
-
@overload
|
222
|
-
def run(
|
223
|
-
self,
|
224
|
-
messages: LanguageModelMessages,
|
225
|
-
instructions: Optional[str] = None,
|
226
|
-
*,
|
227
|
-
stream: Literal[True],
|
228
|
-
model: Optional[LanguageModelName | str] = None,
|
229
|
-
base_url: Optional[str] = None,
|
230
|
-
api_key: Optional[str] = None,
|
231
|
-
temperature: Optional[float] = None,
|
232
|
-
max_tokens: Optional[int] = None,
|
233
|
-
top_p: Optional[float] = None,
|
234
|
-
tools: Optional[List[Any]] = None,
|
235
|
-
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
236
|
-
timeout: Optional[Union[float, str, "Timeout"]] = None,
|
237
|
-
presence_penalty: Optional[float] = None,
|
238
|
-
frequency_penalty: Optional[float] = None,
|
239
|
-
seed: Optional[int] = None,
|
240
|
-
user: Optional[str] = None,
|
241
|
-
mock_response: Optional[str] = None,
|
242
|
-
**kwargs: Any,
|
243
|
-
) -> LanguageModelStream[str]: ...
|
244
|
-
|
245
|
-
@overload
|
246
|
-
def run(
|
247
|
-
self,
|
248
|
-
messages: LanguageModelMessages,
|
249
|
-
instructions: Optional[str] = None,
|
250
|
-
*,
|
251
|
-
type: Type[T],
|
252
|
-
stream: Literal[False] = False,
|
253
|
-
model: Optional[LanguageModelName | str] = None,
|
254
|
-
base_url: Optional[str] = None,
|
255
|
-
api_key: Optional[str] = None,
|
256
|
-
mock_response: Optional[str] = None,
|
257
|
-
**kwargs: Any,
|
258
|
-
) -> LanguageModelResponse[T]: ...
|
259
|
-
|
260
|
-
@overload
|
261
|
-
def run(
|
262
|
-
self,
|
263
|
-
messages: LanguageModelMessages,
|
264
|
-
instructions: Optional[str] = None,
|
265
|
-
*,
|
266
|
-
type: Type[T],
|
267
|
-
stream: Literal[False] = False,
|
268
|
-
model: Optional[LanguageModelName | str] = None,
|
269
|
-
base_url: Optional[str] = None,
|
270
|
-
api_key: Optional[str] = None,
|
271
|
-
temperature: Optional[float] = None,
|
272
|
-
max_tokens: Optional[int] = None,
|
273
|
-
top_p: Optional[float] = None,
|
274
|
-
instructor_mode: Optional[LanguageModelInstructorMode] = None,
|
275
|
-
response_field_name: Optional[str] = None,
|
276
|
-
response_field_instruction: Optional[str] = None,
|
277
|
-
response_model_name: Optional[str] = None,
|
278
|
-
max_retries: Optional[int] = None,
|
279
|
-
strict: Optional[bool] = None,
|
280
|
-
validation_context: Optional[Dict[str, Any]] = None,
|
281
|
-
context: Optional[Dict[str, Any]] = None,
|
282
|
-
completion_kwargs_hooks: Optional[List[Callable[..., None]]] = None,
|
283
|
-
completion_response_hooks: Optional[List[Callable[..., None]]] = None,
|
284
|
-
completion_error_hooks: Optional[List[Callable[..., None]]] = None,
|
285
|
-
completion_last_attempt_hooks: Optional[List[Callable[..., None]]] = None,
|
286
|
-
parse_error_hooks: Optional[List[Callable[..., None]]] = None,
|
287
|
-
timeout: Optional[Union[float, str, "Timeout"]] = None,
|
288
|
-
presence_penalty: Optional[float] = None,
|
289
|
-
frequency_penalty: Optional[float] = None,
|
290
|
-
seed: Optional[int] = None,
|
291
|
-
user: Optional[str] = None,
|
292
|
-
mock_response: Optional[str] = None,
|
293
|
-
**kwargs: Any,
|
294
|
-
) -> LanguageModelResponse[T]: ...
|
295
|
-
|
296
|
-
@overload
|
297
|
-
def run(
|
298
|
-
self,
|
299
|
-
messages: LanguageModelMessages,
|
300
|
-
instructions: Optional[str] = None,
|
301
|
-
*,
|
302
|
-
type: Type[T],
|
303
|
-
stream: Literal[True],
|
304
|
-
model: Optional[LanguageModelName | str] = None,
|
305
|
-
base_url: Optional[str] = None,
|
306
|
-
api_key: Optional[str] = None,
|
307
|
-
mock_response: Optional[str] = None,
|
308
|
-
**kwargs: Any,
|
309
|
-
) -> LanguageModelStream[T]: ...
|
310
|
-
|
311
|
-
@overload
|
312
|
-
def run(
|
313
|
-
self,
|
314
|
-
messages: LanguageModelMessages,
|
315
|
-
instructions: Optional[str] = None,
|
316
|
-
*,
|
317
|
-
type: Type[T],
|
318
|
-
stream: Literal[True],
|
319
|
-
model: Optional[LanguageModelName | str] = None,
|
320
|
-
base_url: Optional[str] = None,
|
321
|
-
api_key: Optional[str] = None,
|
322
|
-
temperature: Optional[float] = None,
|
323
|
-
max_tokens: Optional[int] = None,
|
324
|
-
top_p: Optional[float] = None,
|
325
|
-
instructor_mode: Optional[LanguageModelInstructorMode] = None,
|
326
|
-
response_field_name: Optional[str] = None,
|
327
|
-
response_field_instruction: Optional[str] = None,
|
328
|
-
response_model_name: Optional[str] = None,
|
329
|
-
max_retries: Optional[int] = None,
|
330
|
-
strict: Optional[bool] = None,
|
331
|
-
validation_context: Optional[Dict[str, Any]] = None,
|
332
|
-
context: Optional[Dict[str, Any]] = None,
|
333
|
-
completion_kwargs_hooks: Optional[List[Callable[..., None]]] = None,
|
334
|
-
completion_response_hooks: Optional[List[Callable[..., None]]] = None,
|
335
|
-
completion_error_hooks: Optional[List[Callable[..., None]]] = None,
|
336
|
-
completion_last_attempt_hooks: Optional[List[Callable[..., None]]] = None,
|
337
|
-
parse_error_hooks: Optional[List[Callable[..., None]]] = None,
|
338
|
-
timeout: Optional[Union[float, str, "Timeout"]] = None,
|
339
|
-
presence_penalty: Optional[float] = None,
|
340
|
-
frequency_penalty: Optional[float] = None,
|
341
|
-
seed: Optional[int] = None,
|
342
|
-
user: Optional[str] = None,
|
343
|
-
mock_response: Optional[str] = None,
|
344
|
-
**kwargs: Any,
|
345
|
-
) -> LanguageModelStream[T]: ...
|
346
|
-
|
347
|
-
def run(
|
348
|
-
self,
|
349
|
-
messages: LanguageModelMessages,
|
350
|
-
instructions: Optional[str] = None,
|
351
|
-
mock_response: Optional[str] = None,
|
352
|
-
verbose: Optional[bool] = None,
|
353
|
-
debug: Optional[bool] = None,
|
354
|
-
**kwargs: Any,
|
355
|
-
) -> Union[LanguageModelResponse[Any], LanguageModelStream[Any]]:
|
356
|
-
"""Run a language model request.
|
357
|
-
|
358
|
-
Args:
|
359
|
-
messages: The input messages/content for the request
|
360
|
-
instructions: Optional system instructions to prepend
|
361
|
-
mock_response: Mock response string for testing (saves API costs)
|
362
|
-
verbose: If True, set logger to INFO level for this request
|
363
|
-
debug: If True, set logger to DEBUG level for this request
|
364
|
-
**kwargs: Additional request parameters
|
365
|
-
|
366
|
-
Returns:
|
367
|
-
LanguageModelResponse or LanguageModelStream depending on parameters
|
368
|
-
"""
|
369
|
-
# Set logger level for this request if specified
|
370
|
-
original_level = logger.level
|
371
|
-
if debug or (debug is None and self.debug):
|
372
|
-
logger.setLevel("DEBUG")
|
373
|
-
elif verbose or (verbose is None and self.verbose):
|
374
|
-
logger.setLevel("INFO")
|
375
|
-
|
376
|
-
logger.info(f"Running LanguageModel request with model: {self.model}")
|
377
|
-
logger.debug(f"LanguageModel request kwargs: {kwargs}")
|
378
|
-
|
379
|
-
try:
|
380
|
-
# Extract model, base_url, api_key, and mock_response from kwargs, using instance defaults
|
381
|
-
model = kwargs.pop("model", None) or self.model
|
382
|
-
base_url = kwargs.pop("base_url", None) or self.base_url
|
383
|
-
api_key = kwargs.pop("api_key", None) or self.api_key
|
384
|
-
mock_response_param = kwargs.pop("mock_response", None) or mock_response
|
385
|
-
|
386
|
-
# Add base_url, api_key, and mock_response to kwargs if they are set
|
387
|
-
if base_url is not None:
|
388
|
-
kwargs["base_url"] = base_url
|
389
|
-
if api_key is not None:
|
390
|
-
kwargs["api_key"] = api_key
|
391
|
-
if mock_response_param is not None:
|
392
|
-
kwargs["mock_response"] = mock_response_param
|
393
|
-
|
394
|
-
# Create the request
|
395
|
-
request = LanguageModelRequestBuilder(
|
396
|
-
messages=messages, instructions=instructions, model=model, **kwargs
|
397
|
-
)
|
398
|
-
|
399
|
-
# Parse messages
|
400
|
-
parsed_messages = parse_messages_input(
|
401
|
-
request.messages, request.instructions
|
402
|
-
)
|
403
|
-
if request.is_structured_output():
|
404
|
-
parsed_messages = format_tool_calls(parsed_messages)
|
405
|
-
|
406
|
-
# Handle different request types
|
407
|
-
if request.is_structured_output():
|
408
|
-
return self._handle_structured_output_request(request, parsed_messages)
|
409
|
-
else:
|
410
|
-
return self._handle_completion_request(request, parsed_messages)
|
411
|
-
|
412
|
-
except Exception as e:
|
413
|
-
raise LanguageModelError(f"Error in language model request: {e}") from e
|
414
|
-
finally:
|
415
|
-
# Restore original logger level
|
416
|
-
if debug is not None or verbose is not None:
|
417
|
-
logger.setLevel(original_level)
|
418
|
-
|
419
|
-
# Overloaded async_run methods for different return types
|
420
|
-
|
421
|
-
@overload
|
422
|
-
async def async_run(
|
423
|
-
self,
|
424
|
-
messages: LanguageModelMessages,
|
425
|
-
instructions: Optional[str] = None,
|
426
|
-
*,
|
427
|
-
stream: Literal[False] = False,
|
428
|
-
model: Optional[LanguageModelName | str] = None,
|
429
|
-
base_url: Optional[str] = None,
|
430
|
-
api_key: Optional[str] = None,
|
431
|
-
mock_response: Optional[str] = None,
|
432
|
-
**kwargs: Any,
|
433
|
-
) -> LanguageModelResponse[str]: ...
|
434
|
-
|
435
|
-
@overload
|
436
|
-
async def async_run(
|
437
|
-
self,
|
438
|
-
messages: LanguageModelMessages,
|
439
|
-
instructions: Optional[str] = None,
|
440
|
-
*,
|
441
|
-
stream: Literal[False] = False,
|
442
|
-
model: Optional[LanguageModelName | str] = None,
|
443
|
-
base_url: Optional[str] = None,
|
444
|
-
api_key: Optional[str] = None,
|
445
|
-
temperature: Optional[float] = None,
|
446
|
-
max_tokens: Optional[int] = None,
|
447
|
-
top_p: Optional[float] = None,
|
448
|
-
tools: Optional[List[Any]] = None,
|
449
|
-
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
450
|
-
timeout: Optional[Union[float, str, "Timeout"]] = None,
|
451
|
-
presence_penalty: Optional[float] = None,
|
452
|
-
frequency_penalty: Optional[float] = None,
|
453
|
-
seed: Optional[int] = None,
|
454
|
-
user: Optional[str] = None,
|
455
|
-
mock_response: Optional[str] = None,
|
456
|
-
**kwargs: Any,
|
457
|
-
) -> LanguageModelResponse[str]: ...
|
458
|
-
|
459
|
-
@overload
|
460
|
-
async def async_run(
|
461
|
-
self,
|
462
|
-
messages: LanguageModelMessages,
|
463
|
-
instructions: Optional[str] = None,
|
464
|
-
*,
|
465
|
-
stream: Literal[True],
|
466
|
-
model: Optional[LanguageModelName | str] = None,
|
467
|
-
base_url: Optional[str] = None,
|
468
|
-
api_key: Optional[str] = None,
|
469
|
-
mock_response: Optional[str] = None,
|
470
|
-
**kwargs: Any,
|
471
|
-
) -> LanguageModelStream[str]: ...
|
472
|
-
|
473
|
-
@overload
|
474
|
-
async def async_run(
|
475
|
-
self,
|
476
|
-
messages: LanguageModelMessages,
|
477
|
-
instructions: Optional[str] = None,
|
478
|
-
*,
|
479
|
-
stream: Literal[True],
|
480
|
-
model: Optional[LanguageModelName | str] = None,
|
481
|
-
base_url: Optional[str] = None,
|
482
|
-
api_key: Optional[str] = None,
|
483
|
-
temperature: Optional[float] = None,
|
484
|
-
max_tokens: Optional[int] = None,
|
485
|
-
top_p: Optional[float] = None,
|
486
|
-
tools: Optional[List[Any]] = None,
|
487
|
-
tool_choice: Optional[Union[str, Dict[str, Any]]] = None,
|
488
|
-
timeout: Optional[Union[float, str, "Timeout"]] = None,
|
489
|
-
presence_penalty: Optional[float] = None,
|
490
|
-
frequency_penalty: Optional[float] = None,
|
491
|
-
seed: Optional[int] = None,
|
492
|
-
user: Optional[str] = None,
|
493
|
-
mock_response: Optional[str] = None,
|
494
|
-
**kwargs: Any,
|
495
|
-
) -> LanguageModelStream[str]: ...
|
496
|
-
|
497
|
-
@overload
|
498
|
-
async def async_run(
|
499
|
-
self,
|
500
|
-
messages: LanguageModelMessages,
|
501
|
-
instructions: Optional[str] = None,
|
502
|
-
*,
|
503
|
-
type: Type[T],
|
504
|
-
stream: Literal[False] = False,
|
505
|
-
model: Optional[LanguageModelName | str] = None,
|
506
|
-
base_url: Optional[str] = None,
|
507
|
-
api_key: Optional[str] = None,
|
508
|
-
mock_response: Optional[str] = None,
|
509
|
-
**kwargs: Any,
|
510
|
-
) -> LanguageModelResponse[T]: ...
|
511
|
-
|
512
|
-
@overload
|
513
|
-
async def async_run(
|
514
|
-
self,
|
515
|
-
messages: LanguageModelMessages,
|
516
|
-
instructions: Optional[str] = None,
|
517
|
-
*,
|
518
|
-
type: Type[T],
|
519
|
-
stream: Literal[False] = False,
|
520
|
-
model: Optional[LanguageModelName | str] = None,
|
521
|
-
base_url: Optional[str] = None,
|
522
|
-
api_key: Optional[str] = None,
|
523
|
-
temperature: Optional[float] = None,
|
524
|
-
max_tokens: Optional[int] = None,
|
525
|
-
top_p: Optional[float] = None,
|
526
|
-
instructor_mode: Optional[LanguageModelInstructorMode] = None,
|
527
|
-
response_field_name: Optional[str] = None,
|
528
|
-
response_field_instruction: Optional[str] = None,
|
529
|
-
response_model_name: Optional[str] = None,
|
530
|
-
max_retries: Optional[int] = None,
|
531
|
-
strict: Optional[bool] = None,
|
532
|
-
validation_context: Optional[Dict[str, Any]] = None,
|
533
|
-
context: Optional[Dict[str, Any]] = None,
|
534
|
-
completion_kwargs_hooks: Optional[List[Callable[..., None]]] = None,
|
535
|
-
completion_response_hooks: Optional[List[Callable[..., None]]] = None,
|
536
|
-
completion_error_hooks: Optional[List[Callable[..., None]]] = None,
|
537
|
-
completion_last_attempt_hooks: Optional[List[Callable[..., None]]] = None,
|
538
|
-
parse_error_hooks: Optional[List[Callable[..., None]]] = None,
|
539
|
-
timeout: Optional[Union[float, str, "Timeout"]] = None,
|
540
|
-
presence_penalty: Optional[float] = None,
|
541
|
-
frequency_penalty: Optional[float] = None,
|
542
|
-
seed: Optional[int] = None,
|
543
|
-
user: Optional[str] = None,
|
544
|
-
mock_response: Optional[str] = None,
|
545
|
-
**kwargs: Any,
|
546
|
-
) -> LanguageModelResponse[T]: ...
|
547
|
-
|
548
|
-
@overload
|
549
|
-
async def async_run(
|
550
|
-
self,
|
551
|
-
messages: LanguageModelMessages,
|
552
|
-
instructions: Optional[str] = None,
|
553
|
-
*,
|
554
|
-
type: Type[T],
|
555
|
-
stream: Literal[True],
|
556
|
-
model: Optional[LanguageModelName | str] = None,
|
557
|
-
base_url: Optional[str] = None,
|
558
|
-
api_key: Optional[str] = None,
|
559
|
-
mock_response: Optional[str] = None,
|
560
|
-
**kwargs: Any,
|
561
|
-
) -> LanguageModelStream[T]: ...
|
562
|
-
|
563
|
-
@overload
|
564
|
-
async def async_run(
|
565
|
-
self,
|
566
|
-
messages: LanguageModelMessages,
|
567
|
-
instructions: Optional[str] = None,
|
568
|
-
*,
|
569
|
-
type: Type[T],
|
570
|
-
stream: Literal[True],
|
571
|
-
model: Optional[LanguageModelName | str] = None,
|
572
|
-
base_url: Optional[str] = None,
|
573
|
-
api_key: Optional[str] = None,
|
574
|
-
temperature: Optional[float] = None,
|
575
|
-
max_tokens: Optional[int] = None,
|
576
|
-
top_p: Optional[float] = None,
|
577
|
-
instructor_mode: Optional[LanguageModelInstructorMode] = None,
|
578
|
-
response_field_name: Optional[str] = None,
|
579
|
-
response_field_instruction: Optional[str] = None,
|
580
|
-
response_model_name: Optional[str] = None,
|
581
|
-
max_retries: Optional[int] = None,
|
582
|
-
strict: Optional[bool] = None,
|
583
|
-
validation_context: Optional[Dict[str, Any]] = None,
|
584
|
-
context: Optional[Dict[str, Any]] = None,
|
585
|
-
completion_kwargs_hooks: Optional[List[Callable[..., None]]] = None,
|
586
|
-
completion_response_hooks: Optional[List[Callable[..., None]]] = None,
|
587
|
-
completion_error_hooks: Optional[List[Callable[..., None]]] = None,
|
588
|
-
completion_last_attempt_hooks: Optional[List[Callable[..., None]]] = None,
|
589
|
-
parse_error_hooks: Optional[List[Callable[..., None]]] = None,
|
590
|
-
timeout: Optional[Union[float, str, "Timeout"]] = None,
|
591
|
-
presence_penalty: Optional[float] = None,
|
592
|
-
frequency_penalty: Optional[float] = None,
|
593
|
-
seed: Optional[int] = None,
|
594
|
-
user: Optional[str] = None,
|
595
|
-
mock_response: Optional[str] = None,
|
596
|
-
**kwargs: Any,
|
597
|
-
) -> LanguageModelStream[T]: ...
|
598
|
-
|
599
|
-
async def async_run(
|
600
|
-
self,
|
601
|
-
messages: LanguageModelMessages,
|
602
|
-
instructions: Optional[str] = None,
|
603
|
-
mock_response: Optional[str] = None,
|
604
|
-
verbose: Optional[bool] = None,
|
605
|
-
debug: Optional[bool] = None,
|
606
|
-
**kwargs: Any,
|
607
|
-
) -> Union[LanguageModelResponse[Any], LanguageModelStream[Any]]:
|
608
|
-
"""Run an async language model request.
|
609
|
-
|
610
|
-
Args:
|
611
|
-
messages: The input messages/content for the request
|
612
|
-
instructions: Optional system instructions to prepend
|
613
|
-
mock_response: Mock response string for testing (saves API costs)
|
614
|
-
verbose: If True, set logger to INFO level for this request
|
615
|
-
debug: If True, set logger to DEBUG level for this request
|
616
|
-
**kwargs: Additional request parameters
|
617
|
-
|
618
|
-
Returns:
|
619
|
-
LanguageModelResponse or LanguageModelAsyncStream depending on parameters
|
620
|
-
"""
|
621
|
-
# Set logger level for this request if specified
|
622
|
-
original_level = logger.level
|
623
|
-
if debug or (debug is None and self.debug):
|
624
|
-
logger.setLevel("DEBUG")
|
625
|
-
elif verbose or (verbose is None and self.verbose):
|
626
|
-
logger.setLevel("INFO")
|
627
|
-
|
628
|
-
logger.info(f"Running async LanguageModel request with model: {self.model}")
|
629
|
-
logger.debug(f"LanguageModel request kwargs: {kwargs}")
|
630
|
-
|
631
|
-
try:
|
632
|
-
# Extract model, base_url, api_key, and mock_response from kwargs, using instance defaults
|
633
|
-
model = kwargs.pop("model", None) or self.model
|
634
|
-
base_url = kwargs.pop("base_url", None) or self.base_url
|
635
|
-
api_key = kwargs.pop("api_key", None) or self.api_key
|
636
|
-
mock_response_param = kwargs.pop("mock_response", None) or mock_response
|
637
|
-
|
638
|
-
# Add base_url, api_key, and mock_response to kwargs if they are set
|
639
|
-
if base_url is not None:
|
640
|
-
kwargs["base_url"] = base_url
|
641
|
-
if api_key is not None:
|
642
|
-
kwargs["api_key"] = api_key
|
643
|
-
if mock_response_param is not None:
|
644
|
-
kwargs["mock_response"] = mock_response_param
|
645
|
-
|
646
|
-
# Create the request
|
647
|
-
request = LanguageModelRequestBuilder(
|
648
|
-
messages=messages, instructions=instructions, model=model, **kwargs
|
649
|
-
)
|
650
|
-
|
651
|
-
# Parse messages
|
652
|
-
parsed_messages = parse_messages_input(
|
653
|
-
request.messages, request.instructions
|
654
|
-
)
|
655
|
-
if request.is_structured_output():
|
656
|
-
parsed_messages = format_tool_calls(parsed_messages)
|
657
|
-
|
658
|
-
# Handle different request types
|
659
|
-
if request.is_structured_output():
|
660
|
-
return await self._handle_async_structured_output_request(
|
661
|
-
request, parsed_messages
|
662
|
-
)
|
663
|
-
else:
|
664
|
-
return await self._handle_async_completion_request(
|
665
|
-
request, parsed_messages
|
666
|
-
)
|
667
|
-
|
668
|
-
except Exception as e:
|
669
|
-
raise LanguageModelError(
|
670
|
-
f"Error in async language model request: {e}"
|
671
|
-
) from e
|
672
|
-
finally:
|
673
|
-
# Restore original logger level
|
674
|
-
if debug is not None or verbose is not None:
|
675
|
-
logger.setLevel(original_level)
|
676
|
-
|
677
|
-
def _handle_completion_request(
|
678
|
-
self, request: LanguageModelRequestBuilder, parsed_messages: List[Any]
|
679
|
-
) -> Union[LanguageModelResponse[str], LanguageModelStream[str]]:
|
680
|
-
"""Handle a standard completion request."""
|
681
|
-
# Get filtered parameters
|
682
|
-
params = handle_completion_request_params(request.get_completion_settings())
|
683
|
-
params["messages"] = parsed_messages
|
684
|
-
|
685
|
-
if request.is_streaming():
|
686
|
-
# Handle streaming - stream parameter is already in params
|
687
|
-
if "stream_options" not in params and "stream_options" in request.settings:
|
688
|
-
params["stream_options"] = request.settings["stream_options"]
|
689
|
-
stream = litellm.completion(**params)
|
690
|
-
return LanguageModelStream(
|
691
|
-
model=request.model,
|
692
|
-
stream=stream,
|
693
|
-
output_type=str,
|
694
|
-
)
|
695
|
-
else:
|
696
|
-
# Handle non-streaming
|
697
|
-
response = litellm.completion(**params)
|
698
|
-
return handle_completion_response(response, request.model)
|
699
|
-
|
700
|
-
async def _handle_async_completion_request(
|
701
|
-
self, request: LanguageModelRequestBuilder, parsed_messages: List[Any]
|
702
|
-
) -> Union[LanguageModelResponse[str], LanguageModelStream[str]]:
|
703
|
-
"""Handle an async standard completion request."""
|
704
|
-
# Get filtered parameters
|
705
|
-
params = handle_completion_request_params(request.get_completion_settings())
|
706
|
-
params["messages"] = parsed_messages
|
707
|
-
|
708
|
-
if request.is_streaming():
|
709
|
-
# Handle streaming - stream parameter is already in params
|
710
|
-
if "stream_options" not in params and "stream_options" in request.settings:
|
711
|
-
params["stream_options"] = request.settings["stream_options"]
|
712
|
-
stream = await litellm.acompletion(**params)
|
713
|
-
return LanguageModelStream(
|
714
|
-
model=request.model,
|
715
|
-
stream=stream,
|
716
|
-
output_type=str,
|
717
|
-
)
|
718
|
-
else:
|
719
|
-
# Handle non-streaming
|
720
|
-
response = await litellm.acompletion(**params)
|
721
|
-
return handle_completion_response(response, request.model)
|
722
|
-
|
723
|
-
def _handle_structured_output_request(
|
724
|
-
self, request: LanguageModelRequestBuilder, parsed_messages: List[Any]
|
725
|
-
) -> Union[LanguageModelResponse[Any], LanguageModelStream[Any]]:
|
726
|
-
"""Handle a structured output request."""
|
727
|
-
# Get filtered parameters
|
728
|
-
params = handle_structured_output_request_params(
|
729
|
-
request.get_structured_output_settings()
|
730
|
-
)
|
731
|
-
params["messages"] = parsed_messages
|
732
|
-
|
733
|
-
# Prepare response model
|
734
|
-
response_model = prepare_response_model(
|
735
|
-
request.get_output_type(),
|
736
|
-
request.get_response_field_name(),
|
737
|
-
request.get_response_field_instruction(),
|
738
|
-
request.get_response_model_name(),
|
739
|
-
)
|
740
|
-
|
741
|
-
# Get instructor client
|
742
|
-
client = self._get_instructor_client(request.get_instructor_mode())
|
743
|
-
|
744
|
-
if request.is_streaming():
|
745
|
-
if isinstance(request.get_output_type(), list):
|
746
|
-
# Handle streaming - stream parameter is already in params
|
747
|
-
stream = client.chat.completions.create_iterable(
|
748
|
-
response_model=response_model,
|
749
|
-
max_retries=request.get_max_retries(),
|
750
|
-
strict=request.get_strict_mode(),
|
751
|
-
**params,
|
752
|
-
)
|
753
|
-
else:
|
754
|
-
# Handle streaming - stream parameter is already in params
|
755
|
-
stream = client.chat.completions.create_partial(
|
756
|
-
response_model=response_model,
|
757
|
-
max_retries=request.get_max_retries(),
|
758
|
-
strict=request.get_strict_mode(),
|
759
|
-
**params,
|
760
|
-
)
|
761
|
-
return LanguageModelStream(
|
762
|
-
model=request.model,
|
763
|
-
stream=stream,
|
764
|
-
output_type=request.get_output_type(),
|
765
|
-
response_field_name=request.get_response_field_name(),
|
766
|
-
)
|
767
|
-
else:
|
768
|
-
# Handle non-streaming
|
769
|
-
response, completion = client.chat.completions.create_with_completion(
|
770
|
-
response_model=response_model,
|
771
|
-
max_retries=request.get_max_retries(),
|
772
|
-
strict=request.get_strict_mode(),
|
773
|
-
**params,
|
774
|
-
)
|
775
|
-
return handle_structured_output_response(
|
776
|
-
response,
|
777
|
-
completion,
|
778
|
-
request.model,
|
779
|
-
request.get_output_type(),
|
780
|
-
request.get_response_field_name(),
|
781
|
-
)
|
782
|
-
|
783
|
-
async def _handle_async_structured_output_request(
|
784
|
-
self, request: LanguageModelRequestBuilder, parsed_messages: List[Any]
|
785
|
-
) -> Union[LanguageModelResponse[Any], LanguageModelStream[Any]]:
|
786
|
-
"""Handle an async structured output request."""
|
787
|
-
# Get filtered parameters
|
788
|
-
params = handle_structured_output_request_params(
|
789
|
-
request.get_structured_output_settings()
|
790
|
-
)
|
791
|
-
params["messages"] = parsed_messages
|
792
|
-
|
793
|
-
# Prepare response model
|
794
|
-
response_model = prepare_response_model(
|
795
|
-
request.get_output_type(),
|
796
|
-
request.get_response_field_name(),
|
797
|
-
request.get_response_field_instruction(),
|
798
|
-
request.get_response_model_name(),
|
799
|
-
)
|
800
|
-
|
801
|
-
# Get async instructor client
|
802
|
-
client = self._get_async_instructor_client(request.get_instructor_mode())
|
803
|
-
|
804
|
-
if request.is_streaming():
|
805
|
-
if isinstance(request.get_output_type(), list):
|
806
|
-
# Handle streaming - stream parameter is already in params
|
807
|
-
stream = client.chat.completions.create_iterable(
|
808
|
-
response_model=response_model,
|
809
|
-
max_retries=request.get_max_retries(),
|
810
|
-
strict=request.get_strict_mode(),
|
811
|
-
**params,
|
812
|
-
)
|
813
|
-
else:
|
814
|
-
# Handle streaming - stream parameter is already in params
|
815
|
-
stream = client.chat.completions.create_partial(
|
816
|
-
response_model=response_model,
|
817
|
-
max_retries=request.get_max_retries(),
|
818
|
-
strict=request.get_strict_mode(),
|
819
|
-
**params,
|
820
|
-
)
|
821
|
-
return LanguageModelStream(
|
822
|
-
model=request.model,
|
823
|
-
stream=stream,
|
824
|
-
output_type=request.get_output_type(),
|
825
|
-
response_field_name=request.get_response_field_name(),
|
826
|
-
)
|
827
|
-
else:
|
828
|
-
# Handle non-streaming
|
829
|
-
response, completion = await client.chat.completions.create_with_completion(
|
830
|
-
response_model=response_model,
|
831
|
-
max_retries=request.get_max_retries(),
|
832
|
-
strict=request.get_strict_mode(),
|
833
|
-
**params,
|
834
|
-
)
|
835
|
-
return handle_structured_output_response(
|
836
|
-
response,
|
837
|
-
completion,
|
838
|
-
request.model,
|
839
|
-
request.get_output_type(),
|
840
|
-
request.get_response_field_name(),
|
841
|
-
)
|
842
|
-
|
843
|
-
def as_tool(
|
844
|
-
self,
|
845
|
-
func: Optional[Callable] = None,
|
846
|
-
*,
|
847
|
-
name: Optional[str] = None,
|
848
|
-
description: Optional[str] = None,
|
849
|
-
instructions: Optional[str] = None,
|
850
|
-
**kwargs: Any,
|
851
|
-
) -> Union[Callable, Any]:
|
852
|
-
"""Convert this language model to a tool that can be used by agents.
|
853
|
-
|
854
|
-
Can be used as a decorator or as a function:
|
855
|
-
|
856
|
-
As a decorator:
|
857
|
-
@model.as_tool()
|
858
|
-
def my_function(param1: str, param2: int) -> MyType:
|
859
|
-
'''Function description'''
|
860
|
-
pass
|
861
|
-
|
862
|
-
As a function:
|
863
|
-
tool = model.as_tool(
|
864
|
-
name="my_tool",
|
865
|
-
description="Tool description",
|
866
|
-
instructions="Custom instructions for the LLM"
|
867
|
-
)
|
868
|
-
|
869
|
-
Args:
|
870
|
-
func: The function to wrap (when used as decorator)
|
871
|
-
name: The name of the tool
|
872
|
-
description: Description of what the tool does
|
873
|
-
instructions: Custom instructions for the LLM generation
|
874
|
-
**kwargs: Additional arguments for tool creation
|
875
|
-
|
876
|
-
Returns:
|
877
|
-
BaseTool or decorated function
|
878
|
-
"""
|
879
|
-
from ...types.base import BaseTool
|
880
|
-
from ....formatting.text.converters import convert_docstring_to_text
|
881
|
-
|
882
|
-
def create_tool_wrapper(target_func: Optional[Callable] = None) -> Any:
|
883
|
-
"""Create a tool wrapper for the language model."""
|
884
|
-
|
885
|
-
if target_func is not None:
|
886
|
-
# Decorator usage - use function signature and docstring
|
887
|
-
sig = inspect.signature(target_func)
|
888
|
-
func_name = name or target_func.__name__
|
889
|
-
|
890
|
-
# Get return type from function signature
|
891
|
-
return_type = (
|
892
|
-
sig.return_annotation
|
893
|
-
if sig.return_annotation != inspect.Signature.empty
|
894
|
-
else str
|
895
|
-
)
|
896
|
-
|
897
|
-
# Extract docstring as system instructions
|
898
|
-
system_instructions = instructions or convert_docstring_to_text(
|
899
|
-
target_func
|
900
|
-
)
|
901
|
-
|
902
|
-
# Create parameter schema from function signature
|
903
|
-
parameters_schema = {"type": "object", "properties": {}, "required": []}
|
904
|
-
|
905
|
-
for param_name, param in sig.parameters.items():
|
906
|
-
param_type = (
|
907
|
-
param.annotation
|
908
|
-
if param.annotation != inspect.Parameter.empty
|
909
|
-
else str
|
910
|
-
)
|
911
|
-
|
912
|
-
# Convert type to JSON schema type
|
913
|
-
if param_type == str:
|
914
|
-
json_type = "string"
|
915
|
-
elif param_type == int:
|
916
|
-
json_type = "integer"
|
917
|
-
elif param_type == float:
|
918
|
-
json_type = "number"
|
919
|
-
elif param_type == bool:
|
920
|
-
json_type = "boolean"
|
921
|
-
elif param_type == list:
|
922
|
-
json_type = "array"
|
923
|
-
elif param_type == dict:
|
924
|
-
json_type = "object"
|
925
|
-
else:
|
926
|
-
json_type = "string" # Default fallback
|
927
|
-
|
928
|
-
parameters_schema["properties"][param_name] = {
|
929
|
-
"type": json_type,
|
930
|
-
"description": f"Parameter {param_name} of type {param_type.__name__ if hasattr(param_type, '__name__') else str(param_type)}",
|
931
|
-
}
|
932
|
-
|
933
|
-
if param.default == inspect.Parameter.empty:
|
934
|
-
parameters_schema["required"].append(param_name)
|
935
|
-
|
936
|
-
# Create partial function with model settings
|
937
|
-
partial_func = functools.partial(
|
938
|
-
self._execute_tool_function,
|
939
|
-
target_func=target_func,
|
940
|
-
return_type=return_type,
|
941
|
-
system_instructions=system_instructions,
|
942
|
-
)
|
943
|
-
|
944
|
-
# Handle async functions
|
945
|
-
if asyncio.iscoroutinefunction(target_func):
|
946
|
-
|
947
|
-
async def async_tool_function(**tool_kwargs: Any) -> Any:
|
948
|
-
return await partial_func(**tool_kwargs)
|
949
|
-
|
950
|
-
return BaseTool(
|
951
|
-
name=func_name,
|
952
|
-
description=description
|
953
|
-
or system_instructions
|
954
|
-
or f"Tool for {func_name}",
|
955
|
-
function=async_tool_function,
|
956
|
-
parameters_json_schema=parameters_schema,
|
957
|
-
**kwargs,
|
958
|
-
)
|
959
|
-
else:
|
960
|
-
|
961
|
-
def sync_tool_function(**tool_kwargs: Any) -> Any:
|
962
|
-
return partial_func(**tool_kwargs)
|
963
|
-
|
964
|
-
return BaseTool(
|
965
|
-
name=func_name,
|
966
|
-
description=description
|
967
|
-
or system_instructions
|
968
|
-
or f"Tool for {func_name}",
|
969
|
-
function=sync_tool_function,
|
970
|
-
parameters_json_schema=parameters_schema,
|
971
|
-
**kwargs,
|
972
|
-
)
|
973
|
-
else:
|
974
|
-
# Function usage - create generic tool
|
975
|
-
tool_name = name or f"language_model_{self.model.replace('/', '_')}"
|
976
|
-
tool_description = (
|
977
|
-
description or f"Language model tool using {self.model}"
|
978
|
-
)
|
979
|
-
|
980
|
-
# Create partial function with model settings
|
981
|
-
partial_func = functools.partial(
|
982
|
-
self._execute_generic_tool, system_instructions=instructions
|
983
|
-
)
|
984
|
-
|
985
|
-
def generic_tool_function(
|
986
|
-
input: str, type: Optional[Type[T]] = None, **tool_kwargs: Any
|
987
|
-
) -> Any:
|
988
|
-
"""Generic tool function that runs the language model."""
|
989
|
-
return partial_func(input=input, output_type=type, **tool_kwargs)
|
990
|
-
|
991
|
-
# Generic parameter schema
|
992
|
-
parameters_schema = {
|
993
|
-
"type": "object",
|
994
|
-
"properties": {
|
995
|
-
"input": {
|
996
|
-
"type": "string",
|
997
|
-
"description": "The input text for the language model",
|
998
|
-
},
|
999
|
-
"type": {
|
1000
|
-
"type": "string",
|
1001
|
-
"description": "Optional output type specification",
|
1002
|
-
},
|
1003
|
-
},
|
1004
|
-
"required": ["input"],
|
1005
|
-
}
|
1006
|
-
|
1007
|
-
return BaseTool(
|
1008
|
-
name=tool_name,
|
1009
|
-
description=tool_description,
|
1010
|
-
function=generic_tool_function,
|
1011
|
-
parameters_json_schema=parameters_schema,
|
1012
|
-
**kwargs,
|
1013
|
-
)
|
1014
|
-
|
1015
|
-
if func is None:
|
1016
|
-
# Called as @model.as_tool() or model.as_tool()
|
1017
|
-
return create_tool_wrapper
|
1018
|
-
else:
|
1019
|
-
# Called as @model.as_tool (without parentheses)
|
1020
|
-
return create_tool_wrapper(func)
|
1021
|
-
|
1022
|
-
def _execute_tool_function(
|
1023
|
-
self,
|
1024
|
-
target_func: Callable,
|
1025
|
-
return_type: Type,
|
1026
|
-
system_instructions: str,
|
1027
|
-
**kwargs: Any,
|
1028
|
-
) -> Any:
|
1029
|
-
"""Execute a function-based tool using the language model."""
|
1030
|
-
# Format the function call parameters
|
1031
|
-
param_text = ", ".join([f"{k}={v}" for k, v in kwargs.items()])
|
1032
|
-
input_text = f"Function: {target_func.__name__}({param_text})"
|
1033
|
-
|
1034
|
-
# Use the language model to generate structured output
|
1035
|
-
if return_type != str:
|
1036
|
-
response = self.run(
|
1037
|
-
messages=[{"role": "user", "content": input_text}],
|
1038
|
-
instructions=system_instructions,
|
1039
|
-
type=return_type,
|
1040
|
-
)
|
1041
|
-
else:
|
1042
|
-
response = self.run(
|
1043
|
-
messages=[{"role": "user", "content": input_text}],
|
1044
|
-
instructions=system_instructions,
|
1045
|
-
)
|
1046
|
-
|
1047
|
-
return response.output
|
1048
|
-
|
1049
|
-
def _execute_generic_tool(
|
1050
|
-
self,
|
1051
|
-
input: str,
|
1052
|
-
output_type: Optional[Type] = None,
|
1053
|
-
system_instructions: Optional[str] = None,
|
1054
|
-
**kwargs: Any,
|
1055
|
-
) -> Any:
|
1056
|
-
"""Execute a generic tool using the language model."""
|
1057
|
-
if output_type and output_type != str:
|
1058
|
-
response = self.run(
|
1059
|
-
messages=[{"role": "user", "content": input}],
|
1060
|
-
instructions=system_instructions,
|
1061
|
-
type=output_type,
|
1062
|
-
**kwargs,
|
1063
|
-
)
|
1064
|
-
else:
|
1065
|
-
response = self.run(
|
1066
|
-
messages=[{"role": "user", "content": input}],
|
1067
|
-
instructions=system_instructions,
|
1068
|
-
**kwargs,
|
1069
|
-
)
|
1070
|
-
|
1071
|
-
return response.output
|
1072
|
-
|
1073
|
-
|
1074
|
-
def create_language_model(
|
1075
|
-
model: str | LanguageModelName = "openai/gpt-4o-mini",
|
1076
|
-
base_url: Optional[str] = None,
|
1077
|
-
api_key: Optional[str] = None,
|
1078
|
-
api_version: Optional[str] = None,
|
1079
|
-
organization: Optional[str] = None,
|
1080
|
-
deployment_id: Optional[str] = None,
|
1081
|
-
model_list: Optional[List[Any]] = None,
|
1082
|
-
extra_headers: Optional[Dict[str, str]] = None,
|
1083
|
-
verbose: bool = False,
|
1084
|
-
debug: bool = False,
|
1085
|
-
) -> LanguageModel:
|
1086
|
-
"""Create a language model instance."""
|
1087
|
-
return LanguageModel(
|
1088
|
-
model=model,
|
1089
|
-
base_url=base_url,
|
1090
|
-
api_key=api_key,
|
1091
|
-
api_version=api_version,
|
1092
|
-
organization=organization,
|
1093
|
-
deployment_id=deployment_id,
|
1094
|
-
model_list=model_list,
|
1095
|
-
extra_headers=extra_headers,
|
1096
|
-
verbose=verbose,
|
1097
|
-
debug=debug,
|
1098
|
-
)
|