promptbuilder 0.4.29__tar.gz → 0.4.31__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.
- {promptbuilder-0.4.29/promptbuilder.egg-info → promptbuilder-0.4.31}/PKG-INFO +4 -1
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/promptbuilder/llm_client/aisuite_client.py +2 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/promptbuilder/llm_client/anthropic_client.py +8 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/promptbuilder/llm_client/base_client.py +67 -40
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/promptbuilder/llm_client/bedrock_client.py +9 -1
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/promptbuilder/llm_client/google_client.py +12 -5
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/promptbuilder/llm_client/litellm_client.py +7 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/promptbuilder/llm_client/main.py +13 -7
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/promptbuilder/llm_client/openai_client.py +11 -1
- promptbuilder-0.4.31/promptbuilder/llm_client/vertex_client.py +394 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31/promptbuilder.egg-info}/PKG-INFO +4 -1
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/promptbuilder.egg-info/SOURCES.txt +5 -1
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/promptbuilder.egg-info/requires.txt +3 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/setup.py +5 -2
- promptbuilder-0.4.31/tests/test_timeout_google.py +78 -0
- promptbuilder-0.4.31/tests/test_timeout_litellm.py +43 -0
- promptbuilder-0.4.31/tests/test_timeout_openai.py +133 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/LICENSE +0 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/MANIFEST.in +0 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/Readme.md +0 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/promptbuilder/__init__.py +0 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/promptbuilder/agent/__init__.py +0 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/promptbuilder/agent/agent.py +0 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/promptbuilder/agent/context.py +0 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/promptbuilder/agent/tool.py +0 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/promptbuilder/agent/utils.py +0 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/promptbuilder/embeddings.py +0 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/promptbuilder/llm_client/__init__.py +0 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/promptbuilder/llm_client/config.py +0 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/promptbuilder/llm_client/exceptions.py +0 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/promptbuilder/llm_client/logfire_decorators.py +0 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/promptbuilder/llm_client/types.py +0 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/promptbuilder/llm_client/utils.py +0 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/promptbuilder/prompt_builder.py +0 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/promptbuilder.egg-info/dependency_links.txt +0 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/promptbuilder.egg-info/top_level.txt +0 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/pyproject.toml +0 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/setup.cfg +0 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/tests/test_llm_client.py +0 -0
- {promptbuilder-0.4.29 → promptbuilder-0.4.31}/tests/test_llm_client_async.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: promptbuilder
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.31
|
|
4
4
|
Summary: Library for building prompts for LLMs
|
|
5
5
|
Home-page: https://github.com/kapulkin/promptbuilder
|
|
6
6
|
Author: Kapulkin Stanislav
|
|
@@ -18,6 +18,9 @@ Requires-Dist: google-genai>=1.4.0
|
|
|
18
18
|
Requires-Dist: anthropic
|
|
19
19
|
Requires-Dist: openai
|
|
20
20
|
Requires-Dist: aioboto3
|
|
21
|
+
Requires-Dist: litellm
|
|
22
|
+
Requires-Dist: httpx
|
|
23
|
+
Requires-Dist: aiohttp
|
|
21
24
|
Dynamic: author
|
|
22
25
|
Dynamic: author-email
|
|
23
26
|
Dynamic: classifier
|
|
@@ -71,6 +71,7 @@ class AiSuiteLLMClient(BaseLLMClient):
|
|
|
71
71
|
thinking_config: ThinkingConfig = ThinkingConfig(),
|
|
72
72
|
system_message: str | None = None,
|
|
73
73
|
max_tokens: int | None = None,
|
|
74
|
+
timeout: float | None = None,
|
|
74
75
|
tools: list[Tool] | None = None,
|
|
75
76
|
tool_config: ToolConfig = ToolConfig(),
|
|
76
77
|
) -> Response:
|
|
@@ -230,6 +231,7 @@ class AiSuiteLLMClientAsync(BaseLLMClientAsync):
|
|
|
230
231
|
thinking_config: ThinkingConfig = ThinkingConfig(),
|
|
231
232
|
system_message: str | None = None,
|
|
232
233
|
max_tokens: int | None = None,
|
|
234
|
+
timeout: float | None = None,
|
|
233
235
|
tools: list[Tool] | None = None,
|
|
234
236
|
tool_config: ToolConfig = ToolConfig(),
|
|
235
237
|
) -> Response:
|
|
@@ -200,6 +200,7 @@ class AnthropicLLMClient(BaseLLMClient):
|
|
|
200
200
|
thinking_config: ThinkingConfig | None = None,
|
|
201
201
|
system_message: str | None = None,
|
|
202
202
|
max_tokens: int | None = None,
|
|
203
|
+
timeout: float | None = None,
|
|
203
204
|
tools: list[Tool] | None = None,
|
|
204
205
|
tool_config: ToolConfig = ToolConfig(),
|
|
205
206
|
) -> Response:
|
|
@@ -215,6 +216,9 @@ class AnthropicLLMClient(BaseLLMClient):
|
|
|
215
216
|
"max_tokens": max_tokens,
|
|
216
217
|
"messages": anthropic_messages,
|
|
217
218
|
}
|
|
219
|
+
|
|
220
|
+
if timeout is not None:
|
|
221
|
+
anthropic_kwargs["timeout"] = timeout
|
|
218
222
|
|
|
219
223
|
if thinking_config is None:
|
|
220
224
|
thinking_config = self.default_thinking_config
|
|
@@ -453,6 +457,7 @@ class AnthropicLLMClientAsync(BaseLLMClientAsync):
|
|
|
453
457
|
thinking_config: ThinkingConfig | None = None,
|
|
454
458
|
system_message: str | None = None,
|
|
455
459
|
max_tokens: int | None = None,
|
|
460
|
+
timeout: float | None = None,
|
|
456
461
|
tools: list[Tool] | None = None,
|
|
457
462
|
tool_config: ToolConfig = ToolConfig(),
|
|
458
463
|
) -> Response:
|
|
@@ -474,6 +479,9 @@ class AnthropicLLMClientAsync(BaseLLMClientAsync):
|
|
|
474
479
|
"max_tokens": max_tokens,
|
|
475
480
|
"messages": anthropic_messages,
|
|
476
481
|
}
|
|
482
|
+
|
|
483
|
+
if timeout is not None:
|
|
484
|
+
anthropic_kwargs["timeout"] = timeout
|
|
477
485
|
|
|
478
486
|
if thinking_config is None:
|
|
479
487
|
thinking_config = self.default_thinking_config
|
|
@@ -82,6 +82,7 @@ class BaseLLMClient(ABC, utils.InheritDecoratorsMixin):
|
|
|
82
82
|
thinking_config: ThinkingConfig | None = None,
|
|
83
83
|
system_message: str | None = None,
|
|
84
84
|
max_tokens: int | None = None,
|
|
85
|
+
timeout: float | None = None,
|
|
85
86
|
tools: list[Tool] | None = None,
|
|
86
87
|
tool_config: ToolConfig = ToolConfig(),
|
|
87
88
|
autocomplete: bool = False
|
|
@@ -98,6 +99,7 @@ class BaseLLMClient(ABC, utils.InheritDecoratorsMixin):
|
|
|
98
99
|
thinking_config=thinking_config,
|
|
99
100
|
system_message=system_message,
|
|
100
101
|
max_tokens=max_tokens,
|
|
102
|
+
timeout=timeout,
|
|
101
103
|
tools=tools,
|
|
102
104
|
tool_config=tool_config,
|
|
103
105
|
)
|
|
@@ -105,25 +107,28 @@ class BaseLLMClient(ABC, utils.InheritDecoratorsMixin):
|
|
|
105
107
|
total_count = BaseLLMClient._response_out_tokens(response)
|
|
106
108
|
|
|
107
109
|
finish_reason = response.candidates[0].finish_reason.value if response.candidates and response.candidates[0].finish_reason else None
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
response.candidates[0].content
|
|
110
|
+
if autocomplete:
|
|
111
|
+
while autocomplete and response.candidates and finish_reason == FinishReason.MAX_TOKENS.value:
|
|
112
|
+
BaseLLMClient._append_generated_part(messages, response)
|
|
113
|
+
|
|
114
|
+
response = self._create(
|
|
115
|
+
messages=messages,
|
|
116
|
+
result_type=result_type,
|
|
117
|
+
thinking_config=thinking_config,
|
|
118
|
+
system_message=system_message,
|
|
119
|
+
max_tokens=max_tokens,
|
|
120
|
+
timeout=timeout,
|
|
121
|
+
tools=tools,
|
|
122
|
+
tool_config=tool_config,
|
|
123
|
+
)
|
|
124
|
+
finish_reason = response.candidates[0].finish_reason.value if response.candidates and response.candidates[0].finish_reason else None
|
|
125
|
+
total_count += BaseLLMClient._response_out_tokens(response)
|
|
126
|
+
if max_tokens is not None and total_count >= max_tokens:
|
|
127
|
+
break
|
|
128
|
+
if response.candidates and response.candidates[0].content:
|
|
129
|
+
appended_message = BaseLLMClient._append_generated_part(messages, response)
|
|
130
|
+
if appended_message is not None:
|
|
131
|
+
response.candidates[0].content = appended_message
|
|
127
132
|
return response
|
|
128
133
|
|
|
129
134
|
@logfire_decorators.create
|
|
@@ -138,6 +143,7 @@ class BaseLLMClient(ABC, utils.InheritDecoratorsMixin):
|
|
|
138
143
|
thinking_config: ThinkingConfig | None = None,
|
|
139
144
|
system_message: str | None = None,
|
|
140
145
|
max_tokens: int | None = None,
|
|
146
|
+
timeout: float | None = None,
|
|
141
147
|
tools: list[Tool] | None = None,
|
|
142
148
|
tool_config: ToolConfig = ToolConfig(),
|
|
143
149
|
) -> Response:
|
|
@@ -152,6 +158,7 @@ class BaseLLMClient(ABC, utils.InheritDecoratorsMixin):
|
|
|
152
158
|
thinking_config: ThinkingConfig | None = None,
|
|
153
159
|
system_message: str | None = None,
|
|
154
160
|
max_tokens: int | None = None,
|
|
161
|
+
timeout: float | None = None,
|
|
155
162
|
tools: None = None,
|
|
156
163
|
tool_choice_mode: Literal["NONE"] = "NONE",
|
|
157
164
|
autocomplete: bool = False,
|
|
@@ -165,6 +172,7 @@ class BaseLLMClient(ABC, utils.InheritDecoratorsMixin):
|
|
|
165
172
|
thinking_config: ThinkingConfig | None = None,
|
|
166
173
|
system_message: str | None = None,
|
|
167
174
|
max_tokens: int | None = None,
|
|
175
|
+
timeout: float | None = None,
|
|
168
176
|
tools: None = None,
|
|
169
177
|
tool_choice_mode: Literal["NONE"] = "NONE",
|
|
170
178
|
autocomplete: bool = False,
|
|
@@ -178,6 +186,7 @@ class BaseLLMClient(ABC, utils.InheritDecoratorsMixin):
|
|
|
178
186
|
thinking_config: ThinkingConfig | None = None,
|
|
179
187
|
system_message: str | None = None,
|
|
180
188
|
max_tokens: int | None = None,
|
|
189
|
+
timeout: float | None = None,
|
|
181
190
|
tools: None = None,
|
|
182
191
|
tool_choice_mode: Literal["NONE"] = "NONE",
|
|
183
192
|
autocomplete: bool = False,
|
|
@@ -191,6 +200,7 @@ class BaseLLMClient(ABC, utils.InheritDecoratorsMixin):
|
|
|
191
200
|
thinking_config: ThinkingConfig | None = None,
|
|
192
201
|
system_message: str | None = None,
|
|
193
202
|
max_tokens: int | None = None,
|
|
203
|
+
timeout: float | None = None,
|
|
194
204
|
tools: list[Tool],
|
|
195
205
|
tool_choice_mode: Literal["ANY"],
|
|
196
206
|
autocomplete: bool = False,
|
|
@@ -204,6 +214,7 @@ class BaseLLMClient(ABC, utils.InheritDecoratorsMixin):
|
|
|
204
214
|
thinking_config: ThinkingConfig | None = None,
|
|
205
215
|
system_message: str | None = None,
|
|
206
216
|
max_tokens: int | None = None,
|
|
217
|
+
timeout: float | None = None,
|
|
207
218
|
tools: list[Tool] | None = None,
|
|
208
219
|
tool_choice_mode: Literal["ANY", "NONE"] = "NONE",
|
|
209
220
|
autocomplete: bool = False,
|
|
@@ -215,6 +226,7 @@ class BaseLLMClient(ABC, utils.InheritDecoratorsMixin):
|
|
|
215
226
|
thinking_config=thinking_config,
|
|
216
227
|
system_message=system_message,
|
|
217
228
|
max_tokens=max_tokens,
|
|
229
|
+
timeout=timeout,
|
|
218
230
|
tools=tools,
|
|
219
231
|
tool_config=ToolConfig(function_calling_config=FunctionCallingConfig(mode=tool_choice_mode)),
|
|
220
232
|
)
|
|
@@ -231,6 +243,7 @@ class BaseLLMClient(ABC, utils.InheritDecoratorsMixin):
|
|
|
231
243
|
thinking_config=thinking_config,
|
|
232
244
|
system_message=system_message,
|
|
233
245
|
max_tokens=max_tokens,
|
|
246
|
+
timeout=timeout,
|
|
234
247
|
tools=tools,
|
|
235
248
|
tool_config=ToolConfig(function_calling_config=FunctionCallingConfig(mode=tool_choice_mode)),
|
|
236
249
|
autocomplete=autocomplete,
|
|
@@ -245,7 +258,7 @@ class BaseLLMClient(ABC, utils.InheritDecoratorsMixin):
|
|
|
245
258
|
|
|
246
259
|
|
|
247
260
|
@staticmethod
|
|
248
|
-
def _append_generated_part(messages: list[Content], response: Response):
|
|
261
|
+
def _append_generated_part(messages: list[Content], response: Response) -> Content | None:
|
|
249
262
|
assert(response.candidates and response.candidates[0].content), "Response must contain at least one candidate with content."
|
|
250
263
|
|
|
251
264
|
text_parts = [
|
|
@@ -262,7 +275,7 @@ class BaseLLMClient(ABC, utils.InheritDecoratorsMixin):
|
|
|
262
275
|
response_text = "".join(part.text for part in thought_parts)
|
|
263
276
|
is_thought = True
|
|
264
277
|
else:
|
|
265
|
-
|
|
278
|
+
return None
|
|
266
279
|
|
|
267
280
|
if len(messages) > 0 and messages[-1].role == "model":
|
|
268
281
|
message_to_append = messages[-1]
|
|
@@ -274,6 +287,7 @@ class BaseLLMClient(ABC, utils.InheritDecoratorsMixin):
|
|
|
274
287
|
message_to_append.parts.append(Part(text=response_text, thought=is_thought))
|
|
275
288
|
else:
|
|
276
289
|
messages.append(Content(parts=[Part(text=response_text, thought=is_thought)], role="model"))
|
|
290
|
+
return messages[-1]
|
|
277
291
|
|
|
278
292
|
@staticmethod
|
|
279
293
|
def _response_out_tokens(response: Response):
|
|
@@ -419,6 +433,7 @@ class BaseLLMClientAsync(ABC, utils.InheritDecoratorsMixin):
|
|
|
419
433
|
thinking_config: ThinkingConfig | None = None,
|
|
420
434
|
system_message: str | None = None,
|
|
421
435
|
max_tokens: int | None = None,
|
|
436
|
+
timeout: float | None = None,
|
|
422
437
|
tools: list[Tool] | None = None,
|
|
423
438
|
tool_config: ToolConfig = ToolConfig(),
|
|
424
439
|
autocomplete: bool = False,
|
|
@@ -435,6 +450,7 @@ class BaseLLMClientAsync(ABC, utils.InheritDecoratorsMixin):
|
|
|
435
450
|
thinking_config=thinking_config,
|
|
436
451
|
system_message=system_message,
|
|
437
452
|
max_tokens=max_tokens,
|
|
453
|
+
timeout=timeout,
|
|
438
454
|
tools=tools,
|
|
439
455
|
tool_config=tool_config,
|
|
440
456
|
)
|
|
@@ -442,25 +458,28 @@ class BaseLLMClientAsync(ABC, utils.InheritDecoratorsMixin):
|
|
|
442
458
|
total_count = BaseLLMClient._response_out_tokens(response)
|
|
443
459
|
|
|
444
460
|
finish_reason = response.candidates[0].finish_reason.value if response.candidates and response.candidates[0].finish_reason else None
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
response.candidates[0].content
|
|
461
|
+
if autocomplete:
|
|
462
|
+
while autocomplete and response.candidates and finish_reason == FinishReason.MAX_TOKENS.value:
|
|
463
|
+
BaseLLMClient._append_generated_part(messages, response)
|
|
464
|
+
|
|
465
|
+
response = await self._create(
|
|
466
|
+
messages=messages,
|
|
467
|
+
result_type=result_type,
|
|
468
|
+
thinking_config=thinking_config,
|
|
469
|
+
system_message=system_message,
|
|
470
|
+
max_tokens=max_tokens,
|
|
471
|
+
timeout=timeout,
|
|
472
|
+
tools=tools,
|
|
473
|
+
tool_config=tool_config,
|
|
474
|
+
)
|
|
475
|
+
finish_reason = response.candidates[0].finish_reason.value if response.candidates and response.candidates[0].finish_reason else None
|
|
476
|
+
total_count += BaseLLMClient._response_out_tokens(response)
|
|
477
|
+
if max_tokens is not None and total_count >= max_tokens:
|
|
478
|
+
break
|
|
479
|
+
if response.candidates and response.candidates[0].content:
|
|
480
|
+
appended_message = BaseLLMClient._append_generated_part(messages, response)
|
|
481
|
+
if appended_message is not None:
|
|
482
|
+
response.candidates[0].content = appended_message
|
|
464
483
|
return response
|
|
465
484
|
|
|
466
485
|
@logfire_decorators.create_async
|
|
@@ -475,6 +494,7 @@ class BaseLLMClientAsync(ABC, utils.InheritDecoratorsMixin):
|
|
|
475
494
|
thinking_config: ThinkingConfig | None = None,
|
|
476
495
|
system_message: str | None = None,
|
|
477
496
|
max_tokens: int | None = None,
|
|
497
|
+
timeout: float | None = None,
|
|
478
498
|
tools: list[Tool] | None = None,
|
|
479
499
|
tool_config: ToolConfig = ToolConfig(),
|
|
480
500
|
) -> Response:
|
|
@@ -489,6 +509,7 @@ class BaseLLMClientAsync(ABC, utils.InheritDecoratorsMixin):
|
|
|
489
509
|
thinking_config: ThinkingConfig | None = None,
|
|
490
510
|
system_message: str | None = None,
|
|
491
511
|
max_tokens: int | None = None,
|
|
512
|
+
timeout: float | None = None,
|
|
492
513
|
tools: None = None,
|
|
493
514
|
tool_choice_mode: Literal["NONE"] = "NONE",
|
|
494
515
|
autocomplete: bool = False,
|
|
@@ -502,6 +523,7 @@ class BaseLLMClientAsync(ABC, utils.InheritDecoratorsMixin):
|
|
|
502
523
|
thinking_config: ThinkingConfig | None = None,
|
|
503
524
|
system_message: str | None = None,
|
|
504
525
|
max_tokens: int | None = None,
|
|
526
|
+
timeout: float | None = None,
|
|
505
527
|
tools: None = None,
|
|
506
528
|
tool_choice_mode: Literal["NONE"] = "NONE",
|
|
507
529
|
autocomplete: bool = False,
|
|
@@ -515,6 +537,7 @@ class BaseLLMClientAsync(ABC, utils.InheritDecoratorsMixin):
|
|
|
515
537
|
thinking_config: ThinkingConfig | None = None,
|
|
516
538
|
system_message: str | None = None,
|
|
517
539
|
max_tokens: int | None = None,
|
|
540
|
+
timeout: float | None = None,
|
|
518
541
|
tools: None = None,
|
|
519
542
|
tool_choice_mode: Literal["NONE"] = "NONE",
|
|
520
543
|
autocomplete: bool = False,
|
|
@@ -528,6 +551,7 @@ class BaseLLMClientAsync(ABC, utils.InheritDecoratorsMixin):
|
|
|
528
551
|
thinking_config: ThinkingConfig | None = None,
|
|
529
552
|
system_message: str | None = None,
|
|
530
553
|
max_tokens: int | None = None,
|
|
554
|
+
timeout: float | None = None,
|
|
531
555
|
tools: list[Tool],
|
|
532
556
|
tool_choice_mode: Literal["ANY"],
|
|
533
557
|
autocomplete: bool = False,
|
|
@@ -541,6 +565,7 @@ class BaseLLMClientAsync(ABC, utils.InheritDecoratorsMixin):
|
|
|
541
565
|
thinking_config: ThinkingConfig | None = None,
|
|
542
566
|
system_message: str | None = None,
|
|
543
567
|
max_tokens: int | None = None,
|
|
568
|
+
timeout: float | None = None,
|
|
544
569
|
tools: list[Tool] | None = None,
|
|
545
570
|
tool_choice_mode: Literal["ANY", "NONE"] = "NONE",
|
|
546
571
|
autocomplete: bool = False,
|
|
@@ -552,6 +577,7 @@ class BaseLLMClientAsync(ABC, utils.InheritDecoratorsMixin):
|
|
|
552
577
|
thinking_config=thinking_config,
|
|
553
578
|
system_message=system_message,
|
|
554
579
|
max_tokens=max_tokens,
|
|
580
|
+
timeout=timeout,
|
|
555
581
|
tools=tools,
|
|
556
582
|
tool_config=ToolConfig(function_calling_config=FunctionCallingConfig(mode=tool_choice_mode)),
|
|
557
583
|
)
|
|
@@ -568,6 +594,7 @@ class BaseLLMClientAsync(ABC, utils.InheritDecoratorsMixin):
|
|
|
568
594
|
thinking_config=thinking_config,
|
|
569
595
|
system_message=system_message,
|
|
570
596
|
max_tokens=max_tokens,
|
|
597
|
+
timeout=timeout,
|
|
571
598
|
tools=tools,
|
|
572
599
|
tool_config=ToolConfig(function_calling_config=FunctionCallingConfig(mode=tool_choice_mode)),
|
|
573
600
|
autocomplete=autocomplete
|
|
@@ -111,6 +111,7 @@ class BedrockLLMClient(BaseLLMClient):
|
|
|
111
111
|
thinking_config: ThinkingConfig | None = None,
|
|
112
112
|
system_message: str | None = None,
|
|
113
113
|
max_tokens: int | None = None,
|
|
114
|
+
timeout: float | None = None,
|
|
114
115
|
tools: list[Tool] | None = None,
|
|
115
116
|
tool_config: ToolConfig = ToolConfig(),
|
|
116
117
|
) -> Response:
|
|
@@ -120,7 +121,10 @@ class BedrockLLMClient(BaseLLMClient):
|
|
|
120
121
|
|
|
121
122
|
if system_message is not None:
|
|
122
123
|
bedrock_kwargs["system"] = [{"text": system_message}]
|
|
123
|
-
|
|
124
|
+
|
|
125
|
+
if timeout is not None:
|
|
126
|
+
bedrock_kwargs["timeout"] = timeout
|
|
127
|
+
|
|
124
128
|
if max_tokens is None:
|
|
125
129
|
max_tokens = self.default_max_tokens
|
|
126
130
|
if max_tokens is not None:
|
|
@@ -407,6 +411,7 @@ class BedrockLLMClientAsync(BaseLLMClientAsync):
|
|
|
407
411
|
thinking_config: ThinkingConfig | None = None,
|
|
408
412
|
system_message: str | None = None,
|
|
409
413
|
max_tokens: int | None = None,
|
|
414
|
+
timeout: float | None = None,
|
|
410
415
|
tools: list[Tool] | None = None,
|
|
411
416
|
tool_config: ToolConfig = ToolConfig(),
|
|
412
417
|
) -> Response:
|
|
@@ -417,6 +422,9 @@ class BedrockLLMClientAsync(BaseLLMClientAsync):
|
|
|
417
422
|
if system_message is not None:
|
|
418
423
|
bedrock_kwargs["system"] = [{"text": system_message}]
|
|
419
424
|
|
|
425
|
+
if timeout is not None:
|
|
426
|
+
bedrock_kwargs["timeout"] = timeout
|
|
427
|
+
|
|
420
428
|
if max_tokens is None:
|
|
421
429
|
max_tokens = self.default_max_tokens
|
|
422
430
|
if max_tokens is not None:
|
|
@@ -57,7 +57,7 @@ class GoogleLLMClient(BaseLLMClient):
|
|
|
57
57
|
raise ValueError("To create a google llm client you need to either set the environment variable GOOGLE_API_KEY or pass the api_key in string format")
|
|
58
58
|
super().__init__(GoogleLLMClient.PROVIDER, model, decorator_configs=decorator_configs, default_thinking_config=default_thinking_config, default_max_tokens=default_max_tokens)
|
|
59
59
|
self._api_key = api_key
|
|
60
|
-
self.client = Client(api_key=api_key)
|
|
60
|
+
self.client = Client(api_key=api_key, **kwargs)
|
|
61
61
|
|
|
62
62
|
@property
|
|
63
63
|
def api_key(self) -> str:
|
|
@@ -95,6 +95,7 @@ class GoogleLLMClient(BaseLLMClient):
|
|
|
95
95
|
thinking_config: ThinkingConfig | None = None,
|
|
96
96
|
system_message: str | None = None,
|
|
97
97
|
max_tokens: int | None = None,
|
|
98
|
+
timeout: float | None = None,
|
|
98
99
|
tools: list[Tool] | None = None,
|
|
99
100
|
tool_config: ToolConfig = ToolConfig(),
|
|
100
101
|
) -> Response:
|
|
@@ -107,6 +108,9 @@ class GoogleLLMClient(BaseLLMClient):
|
|
|
107
108
|
tools=tools,
|
|
108
109
|
tool_config=tool_config,
|
|
109
110
|
)
|
|
111
|
+
if timeout is not None:
|
|
112
|
+
# Google processes timeout via HttpOptions on the request/config
|
|
113
|
+
config.http_options = types.HttpOptions(timeout=int(timeout * 1_000))
|
|
110
114
|
|
|
111
115
|
if thinking_config is None:
|
|
112
116
|
thinking_config = self.default_thinking_config
|
|
@@ -233,8 +237,8 @@ class GoogleLLMClientAsync(BaseLLMClientAsync):
|
|
|
233
237
|
raise ValueError("To create a google llm client you need to either set the environment variable GOOGLE_API_KEY or pass the api_key in string format")
|
|
234
238
|
super().__init__(GoogleLLMClientAsync.PROVIDER, model, decorator_configs=decorator_configs, default_thinking_config=default_thinking_config, default_max_tokens=default_max_tokens)
|
|
235
239
|
self._api_key = api_key
|
|
236
|
-
self.client = Client(api_key=api_key)
|
|
237
|
-
|
|
240
|
+
self.client = Client(api_key=api_key, **kwargs)
|
|
241
|
+
|
|
238
242
|
@property
|
|
239
243
|
def api_key(self) -> str:
|
|
240
244
|
return self._api_key
|
|
@@ -248,6 +252,7 @@ class GoogleLLMClientAsync(BaseLLMClientAsync):
|
|
|
248
252
|
thinking_config: ThinkingConfig | None = None,
|
|
249
253
|
system_message: str | None = None,
|
|
250
254
|
max_tokens: int | None = None,
|
|
255
|
+
timeout: float | None = None,
|
|
251
256
|
tools: list[Tool] | None = None,
|
|
252
257
|
tool_config: ToolConfig = ToolConfig(),
|
|
253
258
|
) -> Response:
|
|
@@ -260,11 +265,13 @@ class GoogleLLMClientAsync(BaseLLMClientAsync):
|
|
|
260
265
|
tools=tools,
|
|
261
266
|
tool_config=tool_config,
|
|
262
267
|
)
|
|
263
|
-
|
|
268
|
+
if timeout is not None:
|
|
269
|
+
config.http_options = types.HttpOptions(timeout=int(timeout * 1_000))
|
|
270
|
+
|
|
264
271
|
if thinking_config is None:
|
|
265
272
|
thinking_config = self.default_thinking_config
|
|
266
273
|
config.thinking_config = thinking_config
|
|
267
|
-
|
|
274
|
+
|
|
268
275
|
if result_type is None or result_type == "json":
|
|
269
276
|
return await self.client.aio.models.generate_content(
|
|
270
277
|
model=self.model,
|
|
@@ -139,6 +139,7 @@ class LiteLLMLLMClient(BaseLLMClient):
|
|
|
139
139
|
thinking_config: ThinkingConfig | None = None,
|
|
140
140
|
system_message: str | None = None,
|
|
141
141
|
max_tokens: int | None = None,
|
|
142
|
+
timeout: float | None = None,
|
|
142
143
|
tools: list[Tool] | None = None,
|
|
143
144
|
tool_config: ToolConfig = ToolConfig(),
|
|
144
145
|
) -> Response:
|
|
@@ -167,6 +168,9 @@ class LiteLLMLLMClient(BaseLLMClient):
|
|
|
167
168
|
|
|
168
169
|
if max_tokens is not None:
|
|
169
170
|
kwargs["max_tokens"] = max_tokens
|
|
171
|
+
if timeout is not None:
|
|
172
|
+
# LiteLLM supports request_timeout in seconds
|
|
173
|
+
kwargs["request_timeout"] = timeout
|
|
170
174
|
|
|
171
175
|
if tools is not None:
|
|
172
176
|
lite_tools = []
|
|
@@ -351,6 +355,7 @@ class LiteLLMLLMClientAsync(BaseLLMClientAsync):
|
|
|
351
355
|
thinking_config: ThinkingConfig | None = None,
|
|
352
356
|
system_message: str | None = None,
|
|
353
357
|
max_tokens: int | None = None,
|
|
358
|
+
timeout: float | None = None,
|
|
354
359
|
tools: list[Tool] | None = None,
|
|
355
360
|
tool_config: ToolConfig = ToolConfig(),
|
|
356
361
|
) -> Response:
|
|
@@ -377,6 +382,8 @@ class LiteLLMLLMClientAsync(BaseLLMClientAsync):
|
|
|
377
382
|
|
|
378
383
|
if max_tokens is not None:
|
|
379
384
|
kwargs["max_tokens"] = max_tokens
|
|
385
|
+
if timeout is not None:
|
|
386
|
+
kwargs["request_timeout"] = timeout
|
|
380
387
|
|
|
381
388
|
if tools is not None:
|
|
382
389
|
lite_tools = []
|
|
@@ -10,7 +10,7 @@ from promptbuilder.llm_client.anthropic_client import AnthropicLLMClient, Anthro
|
|
|
10
10
|
from promptbuilder.llm_client.openai_client import OpenaiLLMClient, OpenaiLLMClientAsync
|
|
11
11
|
from promptbuilder.llm_client.bedrock_client import BedrockLLMClient, BedrockLLMClientAsync
|
|
12
12
|
from promptbuilder.llm_client.aisuite_client import AiSuiteLLMClient, AiSuiteLLMClientAsync
|
|
13
|
-
from promptbuilder.llm_client.litellm_client import
|
|
13
|
+
from promptbuilder.llm_client.litellm_client import LiteLLMClient, LiteLLMClientAsync
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
|
|
@@ -24,14 +24,17 @@ def get_client(
|
|
|
24
24
|
decorator_configs: DecoratorConfigs | None = None,
|
|
25
25
|
default_thinking_config: ThinkingConfig | None = None,
|
|
26
26
|
default_max_tokens: int | None = None,
|
|
27
|
+
**kwargs,
|
|
27
28
|
) -> BaseLLMClient:
|
|
28
29
|
global _memory
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
explicit_kwargs = {
|
|
31
32
|
"decorator_configs": decorator_configs,
|
|
32
33
|
"default_thinking_config": default_thinking_config,
|
|
33
34
|
"default_max_tokens": default_max_tokens,
|
|
34
35
|
}
|
|
36
|
+
# Merge explicit kwargs with additional kwargs, with explicit taking precedence
|
|
37
|
+
merged_kwargs = {**kwargs, **explicit_kwargs}
|
|
35
38
|
provider_to_client_class: dict[str, type[BaseLLMClient]] = {
|
|
36
39
|
"google": GoogleLLMClient,
|
|
37
40
|
"anthropic": AnthropicLLMClient,
|
|
@@ -41,9 +44,9 @@ def get_client(
|
|
|
41
44
|
provider, model = full_model_name.split(":", 1)
|
|
42
45
|
if provider in provider_to_client_class:
|
|
43
46
|
client_class = provider_to_client_class[provider]
|
|
44
|
-
client = client_class(model, api_key, **
|
|
47
|
+
client = client_class(model, api_key, **merged_kwargs)
|
|
45
48
|
else:
|
|
46
|
-
client =
|
|
49
|
+
client = LiteLLMClient(full_model_name, api_key, **merged_kwargs)
|
|
47
50
|
|
|
48
51
|
if (full_model_name, client.api_key) in _memory:
|
|
49
52
|
client = _memory[(full_model_name, client.api_key)]
|
|
@@ -65,14 +68,17 @@ def get_async_client(
|
|
|
65
68
|
decorator_configs: DecoratorConfigs | None = None,
|
|
66
69
|
default_thinking_config: ThinkingConfig | None = None,
|
|
67
70
|
default_max_tokens: int | None = None,
|
|
71
|
+
**kwargs,
|
|
68
72
|
) -> BaseLLMClientAsync:
|
|
69
73
|
global _memory_async
|
|
70
74
|
|
|
71
|
-
|
|
75
|
+
explicit_kwargs = {
|
|
72
76
|
"decorator_configs": decorator_configs,
|
|
73
77
|
"default_thinking_config": default_thinking_config,
|
|
74
78
|
"default_max_tokens": default_max_tokens,
|
|
75
79
|
}
|
|
80
|
+
# Merge explicit kwargs with additional kwargs, with explicit taking precedence
|
|
81
|
+
merged_kwargs = {**kwargs, **explicit_kwargs}
|
|
76
82
|
provider_to_client_class: dict[str, type[BaseLLMClientAsync]] = {
|
|
77
83
|
"google": GoogleLLMClientAsync,
|
|
78
84
|
"anthropic": AnthropicLLMClientAsync,
|
|
@@ -82,9 +88,9 @@ def get_async_client(
|
|
|
82
88
|
provider, model = full_model_name.split(":", 1)
|
|
83
89
|
if provider in provider_to_client_class:
|
|
84
90
|
client_class = provider_to_client_class[provider]
|
|
85
|
-
client = client_class(model, api_key, **
|
|
91
|
+
client = client_class(model, api_key, **merged_kwargs)
|
|
86
92
|
else:
|
|
87
|
-
client =
|
|
93
|
+
client = LiteLLMClientAsync(full_model_name, api_key, **merged_kwargs)
|
|
88
94
|
|
|
89
95
|
if (full_model_name, client.api_key) in _memory_async:
|
|
90
96
|
client = _memory_async[(full_model_name, client.api_key)]
|
|
@@ -150,6 +150,7 @@ class OpenaiLLMClient(BaseLLMClient):
|
|
|
150
150
|
thinking_config: ThinkingConfig | None = None,
|
|
151
151
|
system_message: str | None = None,
|
|
152
152
|
max_tokens: int | None = None,
|
|
153
|
+
timeout: float | None = None,
|
|
153
154
|
tools: list[Tool] | None = None,
|
|
154
155
|
tool_config: ToolConfig = ToolConfig(),
|
|
155
156
|
) -> Response:
|
|
@@ -205,6 +206,9 @@ class OpenaiLLMClient(BaseLLMClient):
|
|
|
205
206
|
openai_kwargs["tool_choice"] = "required"
|
|
206
207
|
|
|
207
208
|
if result_type is None or result_type == "json":
|
|
209
|
+
# Forward timeout to OpenAI per-request if provided
|
|
210
|
+
if timeout is not None:
|
|
211
|
+
openai_kwargs["timeout"] = timeout
|
|
208
212
|
response = self.client.responses.create(**openai_kwargs)
|
|
209
213
|
|
|
210
214
|
parts: list[Part] = []
|
|
@@ -227,6 +231,8 @@ class OpenaiLLMClient(BaseLLMClient):
|
|
|
227
231
|
),
|
|
228
232
|
)
|
|
229
233
|
elif isinstance(result_type, type(BaseModel)):
|
|
234
|
+
if timeout is not None:
|
|
235
|
+
openai_kwargs["timeout"] = timeout
|
|
230
236
|
response = self.client.responses.parse(**openai_kwargs, text_format=result_type)
|
|
231
237
|
|
|
232
238
|
parts: list[Part] = []
|
|
@@ -385,6 +391,7 @@ class OpenaiLLMClientAsync(BaseLLMClientAsync):
|
|
|
385
391
|
thinking_config: ThinkingConfig | None = None,
|
|
386
392
|
system_message: str | None = None,
|
|
387
393
|
max_tokens: int | None = None,
|
|
394
|
+
timeout: float | None = None,
|
|
388
395
|
tools: list[Tool] | None = None,
|
|
389
396
|
tool_config: ToolConfig = ToolConfig(),
|
|
390
397
|
) -> Response:
|
|
@@ -447,8 +454,9 @@ class OpenaiLLMClientAsync(BaseLLMClientAsync):
|
|
|
447
454
|
openai_kwargs["tool_choice"] = "required"
|
|
448
455
|
|
|
449
456
|
if result_type is None or result_type == "json":
|
|
457
|
+
if timeout is not None:
|
|
458
|
+
openai_kwargs["timeout"] = timeout
|
|
450
459
|
response = await self.client.responses.create(**openai_kwargs)
|
|
451
|
-
|
|
452
460
|
parts: list[Part] = []
|
|
453
461
|
for output_item in response.output:
|
|
454
462
|
if output_item.type == "message":
|
|
@@ -469,6 +477,8 @@ class OpenaiLLMClientAsync(BaseLLMClientAsync):
|
|
|
469
477
|
),
|
|
470
478
|
)
|
|
471
479
|
elif isinstance(result_type, type(BaseModel)):
|
|
480
|
+
if timeout is not None:
|
|
481
|
+
openai_kwargs["timeout"] = timeout
|
|
472
482
|
response = await self.client.responses.parse(**openai_kwargs, text_format=result_type)
|
|
473
483
|
|
|
474
484
|
parts: list[Part] = []
|