add multi part conversation support

This commit is contained in:
Ishaan Jaffer 2026-02-03 12:49:50 -08:00
parent 1e5976eb0e
commit 3a31d80eb0
2 changed files with 52 additions and 15 deletions

View file

@ -12,7 +12,11 @@ from litellm.llms.base_llm.chat.transformation import BaseConfig, BaseLLMExcepti
from litellm.types.llms.openai import AllMessageValues
from litellm.types.utils import Choices, Message, ModelResponse
from ..common_utils import A2AError, extract_text_from_a2a_response
from ..common_utils import (
A2AError,
convert_messages_to_prompt,
extract_text_from_a2a_response,
)
from .streaming_iterator import A2AModelResponseIterator
@ -140,24 +144,19 @@ class A2AConfig(BaseConfig):
# Generate request ID
request_id = str(uuid.uuid4())
# Convert last message to A2A format (A2A protocol typically sends single message)
# For multi-turn conversations, we'd need to handle context differently
if not messages:
raise ValueError("At least one message is required for A2A completion")
last_message = messages[-1]
# Convert all messages to maintain conversation history
# Use helper to format conversation with role prefixes
full_context = convert_messages_to_prompt(messages)
# Convert to dict if needed
msg_dict: Dict[str, Any]
if isinstance(last_message, BaseModel):
msg_dict = last_message.model_dump()
elif isinstance(last_message, dict):
msg_dict = cast(Dict[str, Any], last_message)
else:
msg_dict = dict(last_message) # type: ignore
# Transform to A2A message format
a2a_message = self._openai_message_to_a2a_message(msg_dict)
# Create single A2A message with full conversation context
a2a_message = {
"role": "user",
"parts": [{"kind": "text", "text": full_context}],
"messageId": str(uuid.uuid4()),
}
# Build JSON-RPC 2.0 request
# For A2A protocol, the method is "message/send" for non-streaming

View file

@ -3,7 +3,13 @@ Common utilities for A2A (Agent-to-Agent) Protocol
"""
from typing import Any, Dict, List
from pydantic import BaseModel
from litellm.litellm_core_utils.prompt_templates.common_utils import (
convert_content_list_to_str,
)
from litellm.llms.base_llm.chat.transformation import BaseLLMException
from litellm.types.llms.openai import AllMessageValues
class A2AError(BaseLLMException):
@ -22,6 +28,38 @@ class A2AError(BaseLLMException):
)
def convert_messages_to_prompt(messages: List[AllMessageValues]) -> str:
"""
Convert OpenAI messages to a single prompt string for A2A agent.
Formats each message as "{role}: {content}" and joins with newlines
to preserve conversation history. Handles both string and list content.
Args:
messages: List of OpenAI-format messages
Returns:
Formatted prompt string with full conversation context
"""
conversation_parts = []
for msg in messages:
# Use LiteLLM's helper to extract text from content (handles both str and list)
content_text = convert_content_list_to_str(message=msg)
# Get role
if isinstance(msg, BaseModel):
role = msg.model_dump().get("role", "user")
elif isinstance(msg, dict):
role = msg.get("role", "user")
else:
role = dict(msg).get("role", "user") # type: ignore
if content_text:
conversation_parts.append(f"{role}: {content_text}")
return "\n".join(conversation_parts)
def extract_text_from_a2a_message(
message: Dict[str, Any], depth: int = 0, max_depth: int = 10
) -> str: