from __future__ import annotations from collections.abc import Mapping from typing import Any ORIGINAL_USER_CONTENT_KEY = "original_user_content" def message_content_to_text(content: Any) -> str: """Extract text from LangChain message content shapes.""" if isinstance(content, str): return content if isinstance(content, list): parts: list[str] = [] for item in content: if isinstance(item, str): parts.append(item) elif isinstance(item, dict): text = item.get("text") if isinstance(text, str): parts.append(text) return "\n".join(part for part in parts if part) return str(content) def get_original_user_content_text(content: Any, additional_kwargs: Mapping[str, Any] | None) -> str: """Return pre-middleware user text when available, otherwise content text.""" original_content = (additional_kwargs or {}).get(ORIGINAL_USER_CONTENT_KEY) if isinstance(original_content, str): return original_content return message_content_to_text(content)