mirror of
https://github.com/Sea-Haven-Industries/open-swe.git
synced 2026-10-03 19:03:21 +00:00
Merge pull request #971 from langchain-ai/yogesh/followup-comments
fix: collect only comments since last agent response for follow-up triggers
This commit is contained in:
commit
09eeb65592
3 changed files with 70 additions and 12 deletions
41
apps/agent/agent/utils/comments.py
Normal file
41
apps/agent/agent/utils/comments.py
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
"""Helpers for Linear comment processing."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Sequence
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
|
def get_recent_comments(
|
||||||
|
comments: Sequence[dict[str, Any]], bot_message_prefixes: Sequence[str]
|
||||||
|
) -> list[dict[str, Any]] | None:
|
||||||
|
"""Return user comments since the last agent response, or None if none.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
comments: Linear issue comments.
|
||||||
|
bot_message_prefixes: Prefixes that identify agent/bot responses.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Chronological list of comments since the last agent response, or None.
|
||||||
|
"""
|
||||||
|
if not comments:
|
||||||
|
return None
|
||||||
|
|
||||||
|
sorted_comments = sorted(
|
||||||
|
comments,
|
||||||
|
key=lambda comment: comment.get("createdAt", ""),
|
||||||
|
reverse=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
recent_user_comments: list[dict[str, Any]] = []
|
||||||
|
for comment in sorted_comments:
|
||||||
|
body = comment.get("body", "")
|
||||||
|
if any(body.startswith(prefix) for prefix in bot_message_prefixes):
|
||||||
|
break # Everything after this is from before the last agent response
|
||||||
|
recent_user_comments.append(comment)
|
||||||
|
|
||||||
|
if not recent_user_comments:
|
||||||
|
return None
|
||||||
|
|
||||||
|
recent_user_comments.reverse()
|
||||||
|
return recent_user_comments
|
||||||
|
|
@ -16,6 +16,7 @@ from langgraph_sdk import get_client
|
||||||
|
|
||||||
# Local import for encryption
|
# Local import for encryption
|
||||||
from .encryption import encrypt_token
|
from .encryption import encrypt_token
|
||||||
|
from .utils.comments import get_recent_comments
|
||||||
from .utils.multimodal import dedupe_urls, extract_image_urls, fetch_image_block
|
from .utils.multimodal import dedupe_urls, extract_image_urls, fetch_image_block
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
@ -602,15 +603,11 @@ async def process_linear_issue( # noqa: PLR0912, PLR0915
|
||||||
comment_ids: set[str] = set()
|
comment_ids: set[str] = set()
|
||||||
comment_id_to_index: dict[str, int] = {}
|
comment_id_to_index: dict[str, int] = {}
|
||||||
if comments:
|
if comments:
|
||||||
last_bot_comment_idx = -1
|
|
||||||
for i, comment in enumerate(comments):
|
for i, comment in enumerate(comments):
|
||||||
comment_id = comment.get("id", "")
|
comment_id = comment.get("id", "")
|
||||||
if comment_id:
|
if comment_id:
|
||||||
comment_ids.add(comment_id)
|
comment_ids.add(comment_id)
|
||||||
comment_id_to_index[comment_id] = i
|
comment_id_to_index[comment_id] = i
|
||||||
body = comment.get("body", "")
|
|
||||||
if any(body.startswith(prefix) for prefix in bot_message_prefixes):
|
|
||||||
last_bot_comment_idx = i
|
|
||||||
|
|
||||||
relevant_comments = []
|
relevant_comments = []
|
||||||
trigger_index = None
|
trigger_index = None
|
||||||
|
|
@ -623,14 +620,7 @@ async def process_linear_issue( # noqa: PLR0912, PLR0915
|
||||||
trigger_index,
|
trigger_index,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
for i, comment in enumerate(comments):
|
relevant_comments = get_recent_comments(comments, bot_message_prefixes)
|
||||||
if i <= last_bot_comment_idx:
|
|
||||||
continue
|
|
||||||
body = comment.get("body", "")
|
|
||||||
if "@openswe" in body.lower():
|
|
||||||
relevant_comments.append(comment)
|
|
||||||
relevant_comments.extend(comments[i + 1 :])
|
|
||||||
break
|
|
||||||
|
|
||||||
if relevant_comments:
|
if relevant_comments:
|
||||||
comments_text = "\n\n## Comments:\n"
|
comments_text = "\n\n## Comments:\n"
|
||||||
|
|
|
||||||
27
apps/agent/tests/test_recent_comments.py
Normal file
27
apps/agent/tests/test_recent_comments.py
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
from agent.utils.comments import get_recent_comments
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_recent_comments_returns_none_for_empty() -> None:
|
||||||
|
assert get_recent_comments([], ("🤖 **Agent Response**",)) is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_recent_comments_returns_none_when_newest_is_bot_message() -> None:
|
||||||
|
comments = [
|
||||||
|
{"body": "🤖 **Agent Response** latest", "createdAt": "2024-01-03T00:00:00Z"},
|
||||||
|
{"body": "user comment", "createdAt": "2024-01-02T00:00:00Z"},
|
||||||
|
]
|
||||||
|
|
||||||
|
assert get_recent_comments(comments, ("🤖 **Agent Response**",)) is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_recent_comments_collects_since_last_bot_message() -> None:
|
||||||
|
comments = [
|
||||||
|
{"body": "first user", "createdAt": "2024-01-01T00:00:00Z"},
|
||||||
|
{"body": "🤖 **Agent Response** done", "createdAt": "2024-01-02T00:00:00Z"},
|
||||||
|
{"body": "follow up 1", "createdAt": "2024-01-03T00:00:00Z"},
|
||||||
|
{"body": "follow up 2", "createdAt": "2024-01-04T00:00:00Z"},
|
||||||
|
]
|
||||||
|
|
||||||
|
result = get_recent_comments(comments, ("🤖 **Agent Response**",))
|
||||||
|
assert result is not None
|
||||||
|
assert [comment["body"] for comment in result] == ["follow up 1", "follow up 2"]
|
||||||
Loading…
Add table
Reference in a new issue