mirror of
https://github.com/OpenHands/OpenHands.git
synced 2025-12-26 05:48:36 +08:00
Fix old string serializer (#4644)
This commit is contained in:
parent
bde978cf0f
commit
1c9cdaf1a2
@ -3,6 +3,7 @@ from dataclasses import dataclass, fields
|
||||
from typing import Optional
|
||||
|
||||
from openhands.core.config.config_utils import get_field_info
|
||||
from openhands.core.logger import LOG_DIR
|
||||
|
||||
LLM_SENSITIVE_FIELDS = ['api_key', 'aws_access_key_id', 'aws_secret_access_key']
|
||||
|
||||
@ -74,7 +75,7 @@ class LLMConfig:
|
||||
disable_vision: bool | None = None
|
||||
caching_prompt: bool = True
|
||||
log_completions: bool = False
|
||||
log_completions_folder: str | None = None
|
||||
log_completions_folder: str = os.path.join(LOG_DIR, 'completions')
|
||||
draft_editor: Optional['LLMConfig'] = None
|
||||
|
||||
def defaults_to_dict(self) -> dict:
|
||||
|
||||
@ -200,7 +200,9 @@ def finalize_config(cfg: AppConfig):
|
||||
parts = cfg.workspace_mount_rewrite.split(':')
|
||||
cfg.workspace_mount_path = base.replace(parts[0], parts[1])
|
||||
|
||||
# make sure log_completions_folder is an absolute path
|
||||
for llm in cfg.llms.values():
|
||||
llm.log_completions_folder = os.path.abspath(llm.log_completions_folder)
|
||||
if llm.embedding_base_url is None:
|
||||
llm.embedding_base_url = llm.base_url
|
||||
|
||||
|
||||
@ -66,6 +66,21 @@ class Message(BaseModel):
|
||||
|
||||
@model_serializer
|
||||
def serialize_model(self) -> dict:
|
||||
# We need two kinds of serializations:
|
||||
# - into a single string: for providers that don't support list of content items (e.g. no vision, no tool calls)
|
||||
# - into a list of content items: the new APIs of providers with vision/prompt caching/tool calls
|
||||
# NOTE: remove this when litellm or providers support the new API
|
||||
if self.cache_enabled or self.vision_enabled or self.tool_call_id is not None:
|
||||
return self._list_serializer()
|
||||
return self._string_serializer()
|
||||
|
||||
def _string_serializer(self):
|
||||
content = '\n'.join(
|
||||
item.text for item in self.content if isinstance(item, TextContent)
|
||||
)
|
||||
return {'content': content, 'role': self.role}
|
||||
|
||||
def _list_serializer(self):
|
||||
content: list[dict] = []
|
||||
role_tool_with_prompt_caching = False
|
||||
for item in self.content:
|
||||
|
||||
@ -78,10 +78,7 @@ def test_message_with_only_text_content_and_vision_disabled():
|
||||
|
||||
expected_serialized_message = {
|
||||
'role': 'user',
|
||||
'content': [
|
||||
{'type': 'text', 'text': 'This is a text message'},
|
||||
{'type': 'text', 'text': 'This is another text message'},
|
||||
],
|
||||
'content': 'This is a text message\nThis is another text message',
|
||||
}
|
||||
|
||||
assert serialized_message == expected_serialized_message
|
||||
@ -110,10 +107,7 @@ def test_message_with_mixed_content_and_vision_disabled():
|
||||
# Expected serialization ignores images and concatenates text
|
||||
expected_serialized_message = {
|
||||
'role': 'user',
|
||||
'content': [
|
||||
{'type': 'text', 'text': 'This is a text message'},
|
||||
{'type': 'text', 'text': 'This is another text message'},
|
||||
],
|
||||
'content': 'This is a text message\nThis is another text message',
|
||||
}
|
||||
|
||||
# Assert serialized message matches expectation
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user