mirror of
https://github.com/Sea-Haven-Industries/open-swe.git
synced 2026-09-30 10:23:14 +00:00
feat: Make error slack messages only visable to user (#1018)
This commit is contained in:
parent
eb47c86c80
commit
659dd71433
3 changed files with 121 additions and 5 deletions
|
|
@ -14,7 +14,7 @@ from langgraph_sdk import get_client
|
|||
|
||||
from ..encryption import encrypt_token
|
||||
from .linear import comment_on_linear_issue
|
||||
from .slack import post_slack_thread_reply
|
||||
from .slack import post_slack_ephemeral_message, post_slack_thread_reply
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -206,7 +206,33 @@ async def leave_failure_comment(
|
|||
slack_thread = configurable.get("slack_thread", {})
|
||||
channel_id = slack_thread.get("channel_id") if isinstance(slack_thread, dict) else None
|
||||
thread_ts = slack_thread.get("thread_ts") if isinstance(slack_thread, dict) else None
|
||||
triggering_user_id = (
|
||||
slack_thread.get("triggering_user_id") if isinstance(slack_thread, dict) else None
|
||||
)
|
||||
if channel_id and thread_ts:
|
||||
if isinstance(triggering_user_id, str) and triggering_user_id:
|
||||
logger.info(
|
||||
"Posting auth failure ephemeral reply to Slack user %s in channel %s thread %s",
|
||||
triggering_user_id,
|
||||
channel_id,
|
||||
thread_ts,
|
||||
)
|
||||
sent = await post_slack_ephemeral_message(
|
||||
channel_id=channel_id,
|
||||
user_id=triggering_user_id,
|
||||
text=message,
|
||||
thread_ts=thread_ts,
|
||||
)
|
||||
if sent:
|
||||
return
|
||||
logger.warning(
|
||||
"Failed to post ephemeral auth failure reply for Slack user %s; falling back to thread reply",
|
||||
triggering_user_id,
|
||||
)
|
||||
else:
|
||||
logger.warning(
|
||||
"Missing Slack triggering_user_id for auth failure reply; falling back to thread reply",
|
||||
)
|
||||
logger.info(
|
||||
"Posting auth failure reply to Slack channel %s thread %s",
|
||||
channel_id,
|
||||
|
|
|
|||
|
|
@ -202,6 +202,39 @@ async def post_slack_thread_reply(channel_id: str, thread_ts: str, text: str) ->
|
|||
return False
|
||||
|
||||
|
||||
async def post_slack_ephemeral_message(
|
||||
channel_id: str, user_id: str, text: str, thread_ts: str | None = None
|
||||
) -> bool:
|
||||
"""Post an ephemeral message visible only to one user."""
|
||||
if not SLACK_BOT_TOKEN:
|
||||
return False
|
||||
|
||||
payload: dict[str, str] = {
|
||||
"channel": channel_id,
|
||||
"user": user_id,
|
||||
"text": text,
|
||||
}
|
||||
if thread_ts:
|
||||
payload["thread_ts"] = thread_ts
|
||||
|
||||
async with httpx.AsyncClient() as http_client:
|
||||
try:
|
||||
response = await http_client.post(
|
||||
f"{SLACK_API_BASE_URL}/chat.postEphemeral",
|
||||
headers=_slack_headers(),
|
||||
json=payload,
|
||||
)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
if not data.get("ok"):
|
||||
logger.warning("Slack chat.postEphemeral failed: %s", data.get("error"))
|
||||
return False
|
||||
return True
|
||||
except httpx.HTTPError:
|
||||
logger.exception("Slack chat.postEphemeral request failed")
|
||||
return False
|
||||
|
||||
|
||||
async def add_slack_reaction(channel_id: str, message_ts: str, emoji: str = "eyes") -> bool:
|
||||
"""Add a reaction to a Slack message."""
|
||||
if not SLACK_BOT_TOKEN:
|
||||
|
|
|
|||
|
|
@ -12,19 +12,76 @@ def test_leave_failure_comment_posts_to_slack_thread(
|
|||
) -> None:
|
||||
called: dict[str, str] = {}
|
||||
|
||||
async def fake_post_slack_thread_reply(channel_id: str, thread_ts: str, message: str) -> bool:
|
||||
async def fake_post_slack_ephemeral_message(
|
||||
channel_id: str, user_id: str, text: str, thread_ts: str | None = None
|
||||
) -> bool:
|
||||
called["channel_id"] = channel_id
|
||||
called["user_id"] = user_id
|
||||
called["thread_ts"] = thread_ts
|
||||
called["message"] = message
|
||||
called["message"] = text
|
||||
return True
|
||||
|
||||
async def fake_post_slack_thread_reply(channel_id: str, thread_ts: str, message: str) -> bool:
|
||||
raise AssertionError("post_slack_thread_reply should not be called when ephemeral succeeds")
|
||||
|
||||
monkeypatch.setattr(auth, "post_slack_ephemeral_message", fake_post_slack_ephemeral_message)
|
||||
monkeypatch.setattr(auth, "post_slack_thread_reply", fake_post_slack_thread_reply)
|
||||
monkeypatch.setattr(
|
||||
auth,
|
||||
"get_config",
|
||||
lambda: {"configurable": {"slack_thread": {"channel_id": "C123", "thread_ts": "1.2"}}},
|
||||
lambda: {
|
||||
"configurable": {
|
||||
"slack_thread": {
|
||||
"channel_id": "C123",
|
||||
"thread_ts": "1.2",
|
||||
"triggering_user_id": "U123",
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
asyncio.run(auth.leave_failure_comment("slack", "auth failed"))
|
||||
|
||||
assert called == {"channel_id": "C123", "thread_ts": "1.2", "message": "auth failed"}
|
||||
assert called == {
|
||||
"channel_id": "C123",
|
||||
"user_id": "U123",
|
||||
"thread_ts": "1.2",
|
||||
"message": "auth failed",
|
||||
}
|
||||
|
||||
|
||||
def test_leave_failure_comment_falls_back_to_slack_thread_when_ephemeral_fails(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
thread_called: dict[str, str] = {}
|
||||
|
||||
async def fake_post_slack_ephemeral_message(
|
||||
channel_id: str, user_id: str, text: str, thread_ts: str | None = None
|
||||
) -> bool:
|
||||
return False
|
||||
|
||||
async def fake_post_slack_thread_reply(channel_id: str, thread_ts: str, message: str) -> bool:
|
||||
thread_called["channel_id"] = channel_id
|
||||
thread_called["thread_ts"] = thread_ts
|
||||
thread_called["message"] = message
|
||||
return True
|
||||
|
||||
monkeypatch.setattr(auth, "post_slack_ephemeral_message", fake_post_slack_ephemeral_message)
|
||||
monkeypatch.setattr(auth, "post_slack_thread_reply", fake_post_slack_thread_reply)
|
||||
monkeypatch.setattr(
|
||||
auth,
|
||||
"get_config",
|
||||
lambda: {
|
||||
"configurable": {
|
||||
"slack_thread": {
|
||||
"channel_id": "C123",
|
||||
"thread_ts": "1.2",
|
||||
"triggering_user_id": "U123",
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
asyncio.run(auth.leave_failure_comment("slack", "auth failed"))
|
||||
|
||||
assert thread_called == {"channel_id": "C123", "thread_ts": "1.2", "message": "auth failed"}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue