mirror of
https://github.com/Sea-Haven-Industries/open-swe.git
synced 2026-10-07 16:19:09 +00:00
Reconcile Slack report feature with dev merge
Dev refactored slack_thread_reply to async and already added post_slack_top_level_message_with_ts; drop the duplicate definition and await the tool in the feature's tests. Refs: #82
This commit is contained in:
parent
b9702adfc5
commit
4d407b98a3
2 changed files with 6 additions and 57 deletions
|
|
@ -444,57 +444,6 @@ async def post_slack_thread_reply(channel_id: str, thread_ts: str, text: str) ->
|
|||
return message_ts is not None
|
||||
|
||||
|
||||
async def post_slack_top_level_message_with_ts(
|
||||
channel_id: str,
|
||||
text: str,
|
||||
*,
|
||||
unfurl_links: bool = True,
|
||||
unfurl_media: bool = True,
|
||||
blocks: list[dict[str, Any]] | None = None,
|
||||
) -> tuple[str | None, str | None]:
|
||||
"""Post a fresh top-level message to a channel and return its ts and error."""
|
||||
if not SLACK_BOT_TOKEN:
|
||||
return None, "missing_slack_bot_token"
|
||||
|
||||
payload: dict[str, Any] = {
|
||||
"channel": channel_id,
|
||||
"text": text,
|
||||
"unfurl_links": unfurl_links,
|
||||
"unfurl_media": unfurl_media,
|
||||
}
|
||||
if blocks:
|
||||
payload["blocks"] = blocks
|
||||
|
||||
async with httpx.AsyncClient() as http_client:
|
||||
try:
|
||||
response = await http_client.post(
|
||||
f"{SLACK_API_BASE_URL}/chat.postMessage",
|
||||
headers=_slack_headers(),
|
||||
json=payload,
|
||||
)
|
||||
if response.status_code == 429:
|
||||
retry_after = response.headers.get("Retry-After")
|
||||
logger.warning("Slack chat.postMessage rate limited (retry-after=%s)", retry_after)
|
||||
if retry_after:
|
||||
return None, f"rate_limited: {retry_after}"
|
||||
return None, "rate_limited"
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
if not data.get("ok"):
|
||||
error = data.get("error")
|
||||
logger.warning("Slack chat.postMessage failed: %s", error)
|
||||
if error == "ratelimited":
|
||||
return None, "rate_limited"
|
||||
return None, error
|
||||
message_ts = data.get("ts")
|
||||
if isinstance(message_ts, str) and message_ts:
|
||||
return message_ts, None
|
||||
return None, None
|
||||
except httpx.HTTPError as exc:
|
||||
logger.exception("Slack chat.postMessage request failed")
|
||||
return None, f"http_error: {type(exc).__name__}"
|
||||
|
||||
|
||||
async def post_slack_ephemeral_message(
|
||||
channel_id: str, user_id: str, text: str, thread_ts: str | None = None
|
||||
) -> bool:
|
||||
|
|
|
|||
|
|
@ -175,16 +175,16 @@ def _channel_only_config() -> dict[str, Any]:
|
|||
return {"configurable": {"slack_thread": {"channel_id": "C9"}}}
|
||||
|
||||
|
||||
def test_slack_thread_reply_requires_channel_id(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
async def test_slack_thread_reply_requires_channel_id(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setattr(slack_reply_tool, "get_config", lambda: {"configurable": {}})
|
||||
|
||||
result = slack_reply_tool.slack_thread_reply("hello")
|
||||
result = await slack_reply_tool.slack_thread_reply("hello")
|
||||
|
||||
assert result["success"] is False
|
||||
assert result["error"] == "Missing slack_thread.channel_id in config"
|
||||
|
||||
|
||||
def test_slack_thread_reply_posts_top_level_when_no_thread_ts(
|
||||
async def test_slack_thread_reply_posts_top_level_when_no_thread_ts(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
captured: dict[str, Any] = {}
|
||||
|
|
@ -205,14 +205,14 @@ def test_slack_thread_reply_posts_top_level_when_no_thread_ts(
|
|||
monkeypatch.setattr(slack_reply_tool, "post_slack_top_level_message_with_ts", fake_top_level)
|
||||
monkeypatch.setattr(slack_reply_tool, "post_slack_thread_reply_with_ts", fail_thread_reply)
|
||||
|
||||
result = slack_reply_tool.slack_thread_reply("Scheduled report")
|
||||
result = await slack_reply_tool.slack_thread_reply("Scheduled report")
|
||||
|
||||
assert result == {"success": True}
|
||||
assert captured["channel_id"] == "C9"
|
||||
assert captured["text"] == "Scheduled report"
|
||||
|
||||
|
||||
def test_slack_thread_reply_top_level_surfaces_not_in_channel(
|
||||
async def test_slack_thread_reply_top_level_surfaces_not_in_channel(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
async def fake_top_level(
|
||||
|
|
@ -226,7 +226,7 @@ def test_slack_thread_reply_top_level_surfaces_not_in_channel(
|
|||
monkeypatch.setattr(slack_reply_tool, "get_config", _channel_only_config)
|
||||
monkeypatch.setattr(slack_reply_tool, "post_slack_top_level_message_with_ts", fake_top_level)
|
||||
|
||||
result = slack_reply_tool.slack_thread_reply("Scheduled report")
|
||||
result = await slack_reply_tool.slack_thread_reply("Scheduled report")
|
||||
|
||||
assert result["success"] is False
|
||||
assert result["slack_error"] == "not_in_channel"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue