fix(zulip): edit_message accepts **kwargs, returns SendResult; use POST for edits
CI / validate (pull_request) Failing after 2s
CI / validate (pull_request) Failing after 2s
The Gateway streaming interface calls edit_message() with finalize=True
and expects SendResult. Fixed:
1. Added **kwargs to edit_message() signature — silently ignores finalize
2. Changed return type from bool to SendResult for Gateway compatibility
3. Switched from PATCH to POST /api/v1/messages/{id} — Zulip docs use
POST for message editing (PATCH returns 405 Method Not Allowed)
4. Same fixes applied to delete_message() and send()
Discovered during Tanko Gen 4 testing.
This commit is contained in:
@@ -853,12 +853,15 @@ class ZulipAdapter(BasePlatformAdapter):
|
||||
content: str,
|
||||
reply_to: Optional[str] = None,
|
||||
metadata: Optional[Dict[str, Any]] = None,
|
||||
**kwargs: Any,
|
||||
) -> SendResult:
|
||||
"""Send a message to a Zulip chat.
|
||||
|
||||
For DMs, chat_id is the user_id. For streams, format is
|
||||
"stream_name:topic". Sends a placeholder first if this is the
|
||||
first message in a turn, then edits it on subsequent calls.
|
||||
|
||||
Accepts **kwargs for Hermes Gateway compatibility.
|
||||
"""
|
||||
# Determine target type and IDs
|
||||
is_dm = not chat_id or ":" not in chat_id
|
||||
@@ -925,19 +928,42 @@ class ZulipAdapter(BasePlatformAdapter):
|
||||
message_id: str,
|
||||
content: str,
|
||||
metadata: Optional[Dict[str, Any]] = None,
|
||||
) -> bool:
|
||||
"""Edit a previously sent Zulip message (for placeholder replacement)."""
|
||||
**kwargs: Any,
|
||||
) -> SendResult:
|
||||
"""Edit a previously sent Zulip message (for placeholder replacement).
|
||||
|
||||
Returns SendResult for Hermes Gateway streaming interface compatibility.
|
||||
Accepts **kwargs (e.g., finalize=True) — extra kwargs are silently ignored.
|
||||
|
||||
Note: Zulip uses POST /api/v1/messages/{message_id} for editing.
|
||||
"""
|
||||
truncated = _truncate(content)
|
||||
payload = {
|
||||
"message_id": int(message_id),
|
||||
"content": truncated,
|
||||
}
|
||||
try:
|
||||
resp, _ = await self._api_call("PATCH", "/api/v1/messages", data=payload)
|
||||
return resp is not None
|
||||
resp, status = await self._api_call(
|
||||
"POST", f"/api/v1/messages/{int(message_id)}",
|
||||
data=payload,
|
||||
)
|
||||
if resp:
|
||||
self._health_stats["send_count"] += 1
|
||||
return SendResult(
|
||||
success=True,
|
||||
message_id=str(resp.get("id", message_id)),
|
||||
)
|
||||
self._health_stats["send_errors"] += 1
|
||||
return SendResult(
|
||||
success=False,
|
||||
error=f"Edit failed (status={status})",
|
||||
)
|
||||
except Exception as e:
|
||||
logger.warning("[%s] Edit message %s error: %s", self.name, message_id, e)
|
||||
return False
|
||||
self._health_stats["send_errors"] += 1
|
||||
return SendResult(
|
||||
success=False,
|
||||
error=str(e),
|
||||
)
|
||||
|
||||
async def send_typing(self, chat_id: str, metadata: Optional[Dict] = None) -> None:
|
||||
"""Send typing indicator to a Zulip chat."""
|
||||
@@ -975,12 +1001,14 @@ class ZulipAdapter(BasePlatformAdapter):
|
||||
return {"name": chat_id, "type": "dm"}
|
||||
|
||||
async def delete_message(
|
||||
self, chat_id: str, message_id: str, metadata: Optional[Dict] = None
|
||||
) -> bool:
|
||||
self, chat_id: str, message_id: str,
|
||||
metadata: Optional[Dict] = None,
|
||||
**kwargs: Any,
|
||||
) -> SendResult:
|
||||
"""Delete a message via Zulip API."""
|
||||
# Zulip doesn't support message deletion via API for bots
|
||||
# Send an empty edit instead
|
||||
return await self.edit_message(chat_id, message_id, "*deleted*")
|
||||
return await self.edit_message(chat_id, message_id, "*deleted*", **kwargs)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Gen 2: Self-test diagnostics
|
||||
|
||||
Reference in New Issue
Block a user