In GeminiLLMAdapter, when translating from the universal LLMContext format, only pull out the first "system" message as the system instruction, and convert subsequent ones into "user" messages. This is a more correct thing to do than simply drop subsequent "system" messages, especially when potentially sharing a context between multiple LLMs.
This commit is contained in:
@@ -161,7 +161,9 @@ class GeminiLLMAdapter(BaseLLMAdapter[GeminiLLMInvocationParams]):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
# Convert standard format to Google format
|
# Convert standard format to Google format
|
||||||
converted = self._from_standard_message(message)
|
converted = self._from_standard_message(
|
||||||
|
message, already_have_system_instruction=bool(system_instruction)
|
||||||
|
)
|
||||||
if isinstance(converted, Content):
|
if isinstance(converted, Content):
|
||||||
# Regular (non-system) message
|
# Regular (non-system) message
|
||||||
messages.append(converted)
|
messages.append(converted)
|
||||||
@@ -187,7 +189,9 @@ class GeminiLLMAdapter(BaseLLMAdapter[GeminiLLMInvocationParams]):
|
|||||||
|
|
||||||
return self.ConvertedMessages(messages=messages, system_instruction=system_instruction)
|
return self.ConvertedMessages(messages=messages, system_instruction=system_instruction)
|
||||||
|
|
||||||
def _from_standard_message(self, message: LLMStandardMessage) -> Content | str:
|
def _from_standard_message(
|
||||||
|
self, message: LLMStandardMessage, already_have_system_instruction: bool
|
||||||
|
) -> Content | str:
|
||||||
"""Convert universal context message to Google Content object.
|
"""Convert universal context message to Google Content object.
|
||||||
|
|
||||||
Handles conversion of text, images, and function calls to Google's
|
Handles conversion of text, images, and function calls to Google's
|
||||||
@@ -196,6 +200,7 @@ class GeminiLLMAdapter(BaseLLMAdapter[GeminiLLMInvocationParams]):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
message: Message in universal context format.
|
message: Message in universal context format.
|
||||||
|
already_have_system_instruction: Whether we already have a system instruction
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Content object with role and parts, or a plain string for system
|
Content object with role and parts, or a plain string for system
|
||||||
@@ -240,12 +245,15 @@ class GeminiLLMAdapter(BaseLLMAdapter[GeminiLLMInvocationParams]):
|
|||||||
role = message["role"]
|
role = message["role"]
|
||||||
content = message.get("content", [])
|
content = message.get("content", [])
|
||||||
if role == "system":
|
if role == "system":
|
||||||
# System instructions are returned as plain text
|
if already_have_system_instruction:
|
||||||
if isinstance(content, str):
|
role = "user" # Convert system message to user role if we already have a system instruction
|
||||||
return content
|
else:
|
||||||
elif isinstance(content, list):
|
# System instructions are returned as plain text
|
||||||
# If content is a list, we assume it's a list of text parts, per the standard
|
if isinstance(content, str):
|
||||||
return " ".join(part["text"] for part in content if part.get("type") == "text")
|
return content
|
||||||
|
elif isinstance(content, list):
|
||||||
|
# If content is a list, we assume it's a list of text parts, per the standard
|
||||||
|
return " ".join(part["text"] for part in content if part.get("type") == "text")
|
||||||
elif role == "assistant":
|
elif role == "assistant":
|
||||||
role = "model"
|
role = "model"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user