fix(gateway): edit streamed message instead of sending duplicate when response_transformed
When a transform_llm_output hook appends content after streaming, the previous fix skipped the final-send suppression which caused the full response to be sent as a NEW message (duplicate). Instead, edit the existing streamed message in-place to append the transformed content, then set already_sent=True. Added stream_consumer.message_id and .accumulated_text public properties.
This commit is contained in:
@@ -17692,6 +17692,28 @@ class GatewayRunner:
|
|||||||
_content_delivered,
|
_content_delivered,
|
||||||
)
|
)
|
||||||
response["already_sent"] = True
|
response["already_sent"] = True
|
||||||
|
elif not _is_empty_sentinel and _transformed and _sc is not None:
|
||||||
|
# Plugin hooks transformed the response after streaming — edit the
|
||||||
|
# existing streamed message instead of sending a duplicate.
|
||||||
|
_sc_msg_id = _sc.message_id
|
||||||
|
if _sc_msg_id:
|
||||||
|
try:
|
||||||
|
await _sc.adapter.edit_message(
|
||||||
|
chat_id=source.chat_id,
|
||||||
|
message_id=_sc_msg_id,
|
||||||
|
content=response["final_response"],
|
||||||
|
finalize=True,
|
||||||
|
)
|
||||||
|
response["already_sent"] = True
|
||||||
|
logger.info(
|
||||||
|
"Edited streamed message %s for session %s to include plugin-transformed content.",
|
||||||
|
_sc_msg_id, session_key or "?",
|
||||||
|
)
|
||||||
|
except Exception as _edit_err:
|
||||||
|
logger.warning(
|
||||||
|
"Failed to edit streamed message for session %s: %s",
|
||||||
|
session_key or "?", _edit_err,
|
||||||
|
)
|
||||||
|
|
||||||
# Schedule deletion of tracked temporary progress bubbles after the
|
# Schedule deletion of tracked temporary progress bubbles after the
|
||||||
# final response lands. Failed runs skip this so bubbles remain as
|
# final response lands. Failed runs skip this so bubbles remain as
|
||||||
|
|||||||
@@ -192,6 +192,16 @@ class GatewayStreamConsumer:
|
|||||||
"""True when the stream consumer delivered the final assistant reply."""
|
"""True when the stream consumer delivered the final assistant reply."""
|
||||||
return self._final_response_sent
|
return self._final_response_sent
|
||||||
|
|
||||||
|
@property
|
||||||
|
def message_id(self) -> str | None:
|
||||||
|
"""The Discord/chat message ID of the last-sent or edited message."""
|
||||||
|
return self._message_id
|
||||||
|
|
||||||
|
@property
|
||||||
|
def accumulated_text(self) -> str:
|
||||||
|
"""The accumulated streamed text (without think-block content)."""
|
||||||
|
return self._accumulated
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def final_content_delivered(self) -> bool:
|
def final_content_delivered(self) -> bool:
|
||||||
"""True when the final response content reached the user, even if
|
"""True when the final response content reached the user, even if
|
||||||
|
|||||||
Reference in New Issue
Block a user