api_base fix + litellm update
frdel committed
Jul 9, 2025 at 10:30 UTC
3b18b86454715bae7cdb33dd029938f5ecc5b2aa
7 files changed
+69
-69
agent.py
+15
-26
@@ -202,25 +202,13 @@ class AgentContext:
202
agent.handle_critical_exception(e)
203
204
205
-@dataclass
206
-class ModelConfig:
207
- provider: models.ModelProvider
208
- name: str
209
- api_base: str = ""
210
- ctx_length: int = 0
211
- limit_requests: int = 0
212
- limit_input: int = 0
213
- limit_output: int = 0
214
- vision: bool = False
215
- kwargs: dict = field(default_factory=dict)
216
-
205
206
@dataclass
207
class AgentConfig:
220
- chat_model: ModelConfig
221
- utility_model: ModelConfig
222
- embeddings_model: ModelConfig
223
- browser_model: ModelConfig
208
+ chat_model: models.ModelConfig
209
+ utility_model: models.ModelConfig
210
+ embeddings_model: models.ModelConfig
211
+ browser_model: models.ModelConfig
212
mcp_servers: str
213
prompts_subdir: str = ""
214
memory_subdir: str = ""
@@ -582,29 +570,30 @@ class Agent:
570
return models.get_chat_model(
571
self.config.chat_model.provider,
572
self.config.chat_model.name,
585
- **self._get_model_kwargs(self.config.chat_model),
573
+ **self.config.chat_model.build_kwargs(),
574
)
575
576
def get_utility_model(self):
577
return models.get_chat_model(
578
self.config.utility_model.provider,
579
self.config.utility_model.name,
592
- **self._get_model_kwargs(self.config.utility_model),
580
+ **self.config.utility_model.build_kwargs(),
581
+ )
582
+
583
+ def get_browser_model(self):
584
+ return models.get_browser_model(
585
+ self.config.browser_model.provider,
586
+ self.config.browser_model.name,
587
+ **self.config.browser_model.build_kwargs(),
588
)
589
590
def get_embedding_model(self):
591
return models.get_embedding_model(
592
self.config.embeddings_model.provider,
593
self.config.embeddings_model.name,
599
- **self._get_model_kwargs(self.config.embeddings_model),
594
+ **self.config.embeddings_model.build_kwargs(),
595
)
596
602
- def _get_model_kwargs(self, model_config: ModelConfig):
603
- kwargs = model_config.kwargs.copy() or {}
604
- if model_config.api_base and "api_base" not in kwargs:
605
- kwargs["api_base"] = model_config.api_base
606
- return kwargs
607
-
597
async def call_utility_model(
598
self,
599
system: str,
@@ -670,7 +659,7 @@ class Agent:
659
return response, reasoning
660
661
async def rate_limiter(
673
- self, model_config: ModelConfig, input: str, background: bool = False
662
+ self, model_config: models.ModelConfig, input: str, background: bool = False
663
):
664
# rate limiter log
665
wait_log = None
initialize.py
+9
-5
@@ -1,5 +1,5 @@
1
import models
2
-from agent import AgentConfig, ModelConfig
2
+from agent import AgentConfig
3
from python.helpers import runtime, settings, defer
4
from python.helpers.print_style import PrintStyle
5
@@ -26,7 +26,8 @@ def initialize_agent():
26
return result
27
28
# chat model from user settings
29
- chat_llm = ModelConfig(
29
+ chat_llm = models.ModelConfig(
30
+ type=models.ModelType.CHAT,
31
provider=models.ModelProvider[current_settings["chat_model_provider"]],
32
name=current_settings["chat_model_name"],
33
api_base=current_settings["chat_model_api_base"],
@@ -39,7 +40,8 @@ def initialize_agent():
40
)
41
42
# utility model from user settings
42
- utility_llm = ModelConfig(
43
+ utility_llm = models.ModelConfig(
44
+ type=models.ModelType.CHAT,
45
provider=models.ModelProvider[current_settings["util_model_provider"]],
46
name=current_settings["util_model_name"],
47
api_base=current_settings["util_model_api_base"],
@@ -50,7 +52,8 @@ def initialize_agent():
52
kwargs=_normalize_model_kwargs(current_settings["util_model_kwargs"]),
53
)
54
# embedding model from user settings
53
- embedding_llm = ModelConfig(
55
+ embedding_llm = models.ModelConfig(
56
+ type=models.ModelType.EMBEDDING,
57
provider=models.ModelProvider[current_settings["embed_model_provider"]],
58
name=current_settings["embed_model_name"],
59
api_base=current_settings["embed_model_api_base"],
@@ -58,7 +61,8 @@ def initialize_agent():
61
kwargs=_normalize_model_kwargs(current_settings["embed_model_kwargs"]),
62
)
63
# browser model from user settings
61
- browser_llm = ModelConfig(
64
+ browser_llm = models.ModelConfig(
65
+ type=models.ModelType.CHAT,
66
provider=models.ModelProvider[current_settings["browser_model_provider"]],
67
name=current_settings["browser_model_name"],
68
api_base=current_settings["browser_model_api_base"],
models.py
+27
-1
@@ -1,3 +1,4 @@
1
+from dataclasses import dataclass, field
2
from enum import Enum
3
import logging
4
import os
@@ -73,6 +74,26 @@ class ModelProvider(Enum):
74
OTHER = "Other OpenAI compatible"
75
76
77
+@dataclass
78
+class ModelConfig:
79
+ type: ModelType
80
+ provider: ModelProvider
81
+ name: str
82
+ api_base: str = ""
83
+ ctx_length: int = 0
84
+ limit_requests: int = 0
85
+ limit_input: int = 0
86
+ limit_output: int = 0
87
+ vision: bool = False
88
+ kwargs: dict = field(default_factory=dict)
89
+
90
+ def build_kwargs(self):
91
+ kwargs = self.kwargs.copy() or {}
92
+ if self.api_base and "api_base" not in kwargs:
93
+ kwargs["api_base"] = self.api_base
94
+ return kwargs
95
+
96
+
97
class ChatChunk(TypedDict):
98
"""Simplified response chunk for chat models."""
99
@@ -233,6 +254,9 @@ class LiteLLMChatWrapper(SimpleChatModel):
254
tokens_callback: Callable[[str, int], Awaitable[None]] | None = None,
255
**kwargs: Any,
256
) -> Tuple[str, str]:
257
+
258
+ turn_off_logging()
259
+
260
if not messages:
261
messages = []
262
# construct messages
@@ -408,7 +432,9 @@ def _get_litellm_embedding(model_name: str, provider_name: str, **kwargs: Any):
432
433
def _parse_chunk(chunk: Any) -> ChatChunk:
434
delta = chunk["choices"][0].get("delta", {})
411
- message = chunk["choices"][0].get("model_extra", {}).get("message", {})
435
+ message = chunk["choices"][0].get("message", {}) or chunk["choices"][0].get(
436
+ "model_extra", {}
437
+ ).get("message", {})
438
response_delta = (
439
delta.get("content", "")
440
if isinstance(delta, dict)
python/helpers/memory.py
+3
-10
@@ -28,7 +28,7 @@ import uuid
28
from python.helpers import knowledge_import
29
from python.helpers.log import Log, LogItem
30
from enum import Enum
31
-from agent import Agent, ModelConfig
31
+from agent import Agent
32
import models
33
import logging
34
@@ -96,7 +96,7 @@ class Memory:
96
@staticmethod
97
def initialize(
98
log_item: LogItem | None,
99
- model_config: ModelConfig,
99
+ model_config: models.ModelConfig,
100
memory_subdir: str,
101
in_memory=False,
102
) -> tuple[MyFaiss, bool]:
@@ -120,17 +120,10 @@ class Memory:
120
os.makedirs(em_dir, exist_ok=True)
121
store = LocalFileStore(em_dir)
122
123
- # HOTFIX TODO: unify with agent.py
124
- def _get_model_kwargs(model_config: ModelConfig):
125
- kwargs = model_config.kwargs.copy() or {}
126
- if model_config.api_base and "api_base" not in kwargs:
127
- kwargs["api_base"] = model_config.api_base
128
- return kwargs
129
-
123
embeddings_model = models.get_embedding_model(
124
model_config.provider,
125
model_config.name,
133
- **_get_model_kwargs(model_config),
126
+ **model_config.build_kwargs(),
127
)
128
embeddings_model_id = files.safe_file_name(
129
model_config.provider.name + "_" + model_config.name
python/helpers/settings.py
+13
-21
@@ -122,6 +122,7 @@ _settings: Settings | None = None
122
123
def convert_out(settings: Settings) -> SettingsOutput:
124
from models import ModelProvider
125
+ default_settings = get_default_settings()
126
127
# main model section
128
chat_model_fields: list[SettingsField] = []
@@ -381,7 +382,7 @@ def convert_out(settings: Settings) -> SettingsOutput:
382
embed_model_section: SettingsSection = {
383
"id": "embed_model",
384
"title": "Embedding Model",
384
- "description": "Settings for the embedding model used by Agent Zero.",
385
+ "description": f"Settings for the embedding model used by Agent Zero.<br><h4>⚠️ No need to change</h4>The default HuggingFace model {default_settings['embed_model_name']} is preloaded and runs locally within the docker container and there's no need to change it unless you have a specific requirements for embedding.",
386
"fields": embed_model_fields,
387
"tab": "agent",
388
}
@@ -408,6 +409,16 @@ def convert_out(settings: Settings) -> SettingsOutput:
409
}
410
)
411
412
+ browser_model_fields.append(
413
+ {
414
+ "id": "browser_model_api_base",
415
+ "title": "Web Browser model API base URL",
416
+ "description": "API base URL for web browser model. Leave empty for default. Only relevant for Azure, local and custom (other) providers.",
417
+ "type": "text",
418
+ "value": settings["browser_model_api_base"],
419
+ }
420
+ )
421
+
422
browser_model_fields.append(
423
{
424
"id": "browser_model_vision",
@@ -436,24 +447,6 @@ def convert_out(settings: Settings) -> SettingsOutput:
447
"tab": "agent",
448
}
449
439
- # # Memory settings section
440
- # memory_fields: list[SettingsField] = []
441
- # memory_fields.append(
442
- # {
443
- # "id": "memory_settings",
444
- # "title": "Memory Settings",
445
- # "description": "<settings for memory>",
446
- # "type": "text",
447
- # "value": "",
448
- # }
449
- # )
450
-
451
- # memory_section: SettingsSection = {
452
- # "id": "memory",
453
- # "title": "Memory Settings",
454
- # "description": "<settings for memory management here>",
455
- # "fields": memory_fields,
456
- # }
450
451
# basic auth section
452
auth_fields: list[SettingsField] = []
@@ -829,9 +822,8 @@ def convert_out(settings: Settings) -> SettingsOutput:
822
agent_section,
823
chat_model_section,
824
util_model_section,
832
- embed_model_section,
825
browser_model_section,
834
- # memory_section,
826
+ embed_model_section,
827
stt_section,
828
api_keys_section,
829
auth_section,
python/tools/browser_agent.py
+1
-5
@@ -125,11 +125,7 @@ class State:
125
)
126
return result
127
128
- model = models.get_browser_model(
129
- provider=self.agent.config.browser_model.provider,
130
- name=self.agent.config.browser_model.name,
131
- **self.agent._get_model_kwargs(self.agent.config.browser_model),
132
- )
128
+ model = self.agent.get_browser_model()
129
130
try:
131
self.use_agent = browser_use.Agent(
requirements.txt
+1
-1
@@ -30,7 +30,7 @@ unstructured-client==0.31.0
30
webcolors==24.6.0
31
nest-asyncio==1.6.0
32
crontab==1.0.1
33
-litellm==1.72.4
33
+litellm==1.74
34
markdownify==1.1.0
35
pymupdf==1.25.3
36
pytesseract==0.3.13