mirror of
https://github.com/Sea-Haven-Industries/open-swe.git
synced 2026-09-30 08:03:15 +00:00
fix: skip no_op injection when PR is committed and user is notified (#1047)
* fix: skip no_op injection when PR is committed and user is notified - Root cause: ensure_no_empty_msg Branch 1 (empty AI message) lacked the same completion checks as Branch 2 (text-only AI message), causing a spurious no_op injection after commit_and_open_pr + user notification - Change: add check_if_model_already_called_commit_and_open_pr AND check_if_model_messaged_user guard to Branch 1 of ensure_no_empty_msg - Verified: 7/100 production traces no longer get an extra LLM call * updated * pass tests --------- Co-authored-by: Auto Fix Bot <auto-fix@langchain.ai> Co-authored-by: Palash Shah <palash@langchain.dev> Co-authored-by: Palash Shah <35114859+Palashio@users.noreply.github.com>
This commit is contained in:
parent
2f38484451
commit
d98cd9ddc1
2 changed files with 92 additions and 0 deletions
|
|
@ -58,6 +58,11 @@ def ensure_no_empty_msg(state: AgentState, runtime: Runtime) -> dict[str, Any] |
|
|||
if check_if_no_op(messages_since_last_human):
|
||||
return None
|
||||
|
||||
if check_if_model_already_called_commit_and_open_pr(
|
||||
messages_since_last_human
|
||||
) and check_if_model_messaged_user(messages_since_last_human):
|
||||
return None
|
||||
|
||||
tc_id = str(uuid4())
|
||||
last_msg.tool_calls = [{"name": "no_op", "args": {}, "id": tc_id}]
|
||||
no_op_tool_msg = ToolMessage(
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
from unittest.mock import MagicMock
|
||||
|
||||
from langchain_core.messages import AIMessage, HumanMessage, ToolMessage
|
||||
|
||||
from agent.middleware.ensure_no_empty_msg import (
|
||||
check_if_confirming_completion,
|
||||
check_if_model_already_called_commit_and_open_pr,
|
||||
check_if_model_messaged_user,
|
||||
ensure_no_empty_msg,
|
||||
get_every_message_since_last_human,
|
||||
)
|
||||
|
||||
|
|
@ -158,3 +161,87 @@ class TestCheckIfConfirmingCompletion:
|
|||
]
|
||||
|
||||
assert check_if_confirming_completion(messages) is True
|
||||
|
||||
|
||||
class TestEnsureNoEmptyMsgCommitAndNotify:
|
||||
"""Tests the branch: commit_and_open_pr was called AND user was messaged -> return None."""
|
||||
|
||||
def _make_runtime(self) -> MagicMock:
|
||||
return MagicMock()
|
||||
|
||||
def test_returns_none_when_pr_opened_and_user_messaged(self) -> None:
|
||||
empty_ai = AIMessage(content="")
|
||||
state = {
|
||||
"messages": [
|
||||
HumanMessage(content="fix the bug"),
|
||||
ToolMessage(content="PR opened", tool_call_id="1", name="commit_and_open_pr"),
|
||||
ToolMessage(content="message sent", tool_call_id="2", name="slack_thread_reply"),
|
||||
empty_ai,
|
||||
]
|
||||
}
|
||||
|
||||
result = ensure_no_empty_msg.after_model(state, self._make_runtime())
|
||||
|
||||
assert result is None
|
||||
|
||||
def test_returns_none_with_linear_comment_instead_of_slack(self) -> None:
|
||||
empty_ai = AIMessage(content="")
|
||||
state = {
|
||||
"messages": [
|
||||
HumanMessage(content="fix the bug"),
|
||||
ToolMessage(content="PR opened", tool_call_id="1", name="commit_and_open_pr"),
|
||||
ToolMessage(content="commented", tool_call_id="2", name="linear_comment"),
|
||||
empty_ai,
|
||||
]
|
||||
}
|
||||
|
||||
result = ensure_no_empty_msg.after_model(state, self._make_runtime())
|
||||
|
||||
assert result is None
|
||||
|
||||
def test_returns_none_with_github_comment_instead_of_slack(self) -> None:
|
||||
empty_ai = AIMessage(content="")
|
||||
state = {
|
||||
"messages": [
|
||||
HumanMessage(content="fix the bug"),
|
||||
ToolMessage(content="PR opened", tool_call_id="1", name="commit_and_open_pr"),
|
||||
ToolMessage(content="commented", tool_call_id="2", name="github_comment"),
|
||||
empty_ai,
|
||||
]
|
||||
}
|
||||
|
||||
result = ensure_no_empty_msg.after_model(state, self._make_runtime())
|
||||
|
||||
assert result is None
|
||||
|
||||
def test_injects_no_op_when_only_pr_opened_but_user_not_messaged(self) -> None:
|
||||
empty_ai = AIMessage(content="")
|
||||
state = {
|
||||
"messages": [
|
||||
HumanMessage(content="fix the bug"),
|
||||
ToolMessage(content="PR opened", tool_call_id="1", name="commit_and_open_pr"),
|
||||
empty_ai,
|
||||
]
|
||||
}
|
||||
|
||||
result = ensure_no_empty_msg.after_model(state, self._make_runtime())
|
||||
|
||||
assert result is not None
|
||||
assert len(result["messages"]) == 2
|
||||
assert result["messages"][0].tool_calls[0]["name"] == "no_op"
|
||||
|
||||
def test_injects_no_op_when_only_user_messaged_but_no_pr(self) -> None:
|
||||
empty_ai = AIMessage(content="")
|
||||
state = {
|
||||
"messages": [
|
||||
HumanMessage(content="fix the bug"),
|
||||
ToolMessage(content="message sent", tool_call_id="1", name="slack_thread_reply"),
|
||||
empty_ai,
|
||||
]
|
||||
}
|
||||
|
||||
result = ensure_no_empty_msg.after_model(state, self._make_runtime())
|
||||
|
||||
assert result is not None
|
||||
assert len(result["messages"]) == 2
|
||||
assert result["messages"][0].tool_calls[0]["name"] == "no_op"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue