mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
Merge branch 'main' of github.com:NousResearch/hermes-agent into feat/ink-refactor
This commit is contained in:
commit
f81dba0da2
128 changed files with 8357 additions and 842 deletions
|
|
@ -734,25 +734,56 @@ def merge_pending_message_event(
|
|||
pending_messages: Dict[str, MessageEvent],
|
||||
session_key: str,
|
||||
event: MessageEvent,
|
||||
*,
|
||||
merge_text: bool = False,
|
||||
) -> None:
|
||||
"""Store or merge a pending event for a session.
|
||||
|
||||
Photo bursts/albums often arrive as multiple near-simultaneous PHOTO
|
||||
events. Merge those into the existing queued event so the next turn sees
|
||||
the whole burst, while non-photo follow-ups still replace the pending
|
||||
event normally.
|
||||
the whole burst.
|
||||
|
||||
When ``merge_text`` is enabled, rapid follow-up TEXT events are appended
|
||||
instead of replacing the pending turn. This is used for Telegram bursty
|
||||
follow-ups so a multi-part user thought is not silently truncated to only
|
||||
the last queued fragment.
|
||||
"""
|
||||
existing = pending_messages.get(session_key)
|
||||
if (
|
||||
existing
|
||||
and getattr(existing, "message_type", None) == MessageType.PHOTO
|
||||
and event.message_type == MessageType.PHOTO
|
||||
):
|
||||
existing.media_urls.extend(event.media_urls)
|
||||
existing.media_types.extend(event.media_types)
|
||||
if event.text:
|
||||
existing.text = BasePlatformAdapter._merge_caption(existing.text, event.text)
|
||||
return
|
||||
if existing:
|
||||
existing_is_photo = getattr(existing, "message_type", None) == MessageType.PHOTO
|
||||
incoming_is_photo = event.message_type == MessageType.PHOTO
|
||||
existing_has_media = bool(existing.media_urls)
|
||||
incoming_has_media = bool(event.media_urls)
|
||||
|
||||
if existing_is_photo and incoming_is_photo:
|
||||
existing.media_urls.extend(event.media_urls)
|
||||
existing.media_types.extend(event.media_types)
|
||||
if event.text:
|
||||
existing.text = BasePlatformAdapter._merge_caption(existing.text, event.text)
|
||||
return
|
||||
|
||||
if existing_has_media or incoming_has_media:
|
||||
if incoming_has_media:
|
||||
existing.media_urls.extend(event.media_urls)
|
||||
existing.media_types.extend(event.media_types)
|
||||
if event.text:
|
||||
if existing.text:
|
||||
existing.text = BasePlatformAdapter._merge_caption(existing.text, event.text)
|
||||
else:
|
||||
existing.text = event.text
|
||||
if existing_is_photo or incoming_is_photo:
|
||||
existing.message_type = MessageType.PHOTO
|
||||
return
|
||||
|
||||
if (
|
||||
merge_text
|
||||
and getattr(existing, "message_type", None) == MessageType.TEXT
|
||||
and event.message_type == MessageType.TEXT
|
||||
):
|
||||
if event.text:
|
||||
existing.text = f"{existing.text}\n{event.text}" if existing.text else event.text
|
||||
return
|
||||
|
||||
pending_messages[session_key] = event
|
||||
|
||||
|
||||
|
|
@ -839,6 +870,11 @@ class BasePlatformAdapter(ABC):
|
|||
# Gateway shutdown cancels these so an old gateway instance doesn't keep
|
||||
# working on a task after --replace or manual restarts.
|
||||
self._background_tasks: set[asyncio.Task] = set()
|
||||
# One-shot callbacks to fire after the main response is delivered.
|
||||
# Keyed by session_key. GatewayRunner uses this to defer
|
||||
# background-review notifications ("💾 Skill created") until the
|
||||
# primary reply has been sent.
|
||||
self._post_delivery_callbacks: Dict[str, Callable] = {}
|
||||
self._expected_cancelled_tasks: set[asyncio.Task] = set()
|
||||
self._busy_session_handler: Optional[Callable[[MessageEvent, str], Awaitable[bool]]] = None
|
||||
# Chats where auto-TTS on voice input is disabled (set by /voice off)
|
||||
|
|
@ -1905,6 +1941,14 @@ class BasePlatformAdapter(ABC):
|
|||
except Exception:
|
||||
pass # Last resort — don't let error reporting crash the handler
|
||||
finally:
|
||||
# Fire any one-shot post-delivery callback registered for this
|
||||
# session (e.g. deferred background-review notifications).
|
||||
_post_cb = getattr(self, "_post_delivery_callbacks", {}).pop(session_key, None)
|
||||
if callable(_post_cb):
|
||||
try:
|
||||
_post_cb()
|
||||
except Exception:
|
||||
pass
|
||||
# Stop typing indicator
|
||||
typing_task.cancel()
|
||||
try:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue