From db05aebc32f1ba6bd843cbe7e14f8f17a9c9c90d Mon Sep 17 00:00:00 2001 From: aran-yogesh Date: Fri, 20 Feb 2026 15:20:49 -0800 Subject: [PATCH] fix: replace removed MessageContent import with ContentBlock from langchain_core --- apps/agent/agent/middleware/open_pr.py | 5 ++-- apps/agent/agent/middleware/post_to_linear.py | 6 ++-- apps/agent/agent/utils/messages.py | 28 +++++++++++++++++++ 3 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 apps/agent/agent/utils/messages.py diff --git a/apps/agent/agent/middleware/open_pr.py b/apps/agent/agent/middleware/open_pr.py index bc5fbb23..6ea657b9 100644 --- a/apps/agent/agent/middleware/open_pr.py +++ b/apps/agent/agent/middleware/open_pr.py @@ -32,6 +32,7 @@ from ..utils.github import ( git_push, ) from ..utils.linear import comment_on_linear_issue +from ..utils.messages import extract_text_content from ..utils.sandbox_state import get_sandbox_backend logger = logging.getLogger(__name__) @@ -78,9 +79,9 @@ async def open_pr_if_needed( if messages: last_message = messages[-1] if isinstance(last_message, dict): - last_message_content = last_message.get("content", "") + last_message_content = extract_text_content(last_message.get("content", "")) elif hasattr(last_message, "content"): - last_message_content = last_message.content + last_message_content = extract_text_content(last_message.content) linear_issue = configurable.get("linear_issue", {}) linear_issue_id = linear_issue.get("id") diff --git a/apps/agent/agent/middleware/post_to_linear.py b/apps/agent/agent/middleware/post_to_linear.py index c8a1c569..760691ed 100644 --- a/apps/agent/agent/middleware/post_to_linear.py +++ b/apps/agent/agent/middleware/post_to_linear.py @@ -14,6 +14,7 @@ from langgraph.config import get_config from langgraph.runtime import Runtime from ..utils.linear import comment_on_linear_issue +from ..utils.messages import extract_text_content from .check_message_queue import LinearNotifyState logger = logging.getLogger(__name__) @@ -96,12 +97,13 @@ async def post_to_linear_after_model( # noqa: PLR0911, PLR0912 if prev_role not in ("human", "user"): return None - if not content or not isinstance(content, str): + content_text = extract_text_content(content) + if not content_text: return None comment = f"""🤖 **Agent Response** -{content}""" +{content_text}""" logger.info("Posting AI response to Linear issue %s", linear_issue_id) success = await comment_on_linear_issue(linear_issue_id, comment) diff --git a/apps/agent/agent/utils/messages.py b/apps/agent/agent/utils/messages.py new file mode 100644 index 00000000..5d352190 --- /dev/null +++ b/apps/agent/agent/utils/messages.py @@ -0,0 +1,28 @@ +"""Helpers for normalizing message content across model providers.""" + +from __future__ import annotations + +from langchain_core.messages import ContentBlock + + +def extract_text_content(content: str | list[ContentBlock]) -> str: + """Extract human-readable text from model message content. + + Supports: + - Plain strings + - OpenAI-style content blocks (list of {"type": "text", "text": ...}) + - Dict wrappers with nested "content" or "text" + """ + + if isinstance(content, str): + return content.strip() + + if not isinstance(content, list): + return "" + + text = "" + for item in content: + if isinstance(item, dict) and "text" in item: + text += item["text"] + + return text.strip()