Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions gateway/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -6456,6 +6456,11 @@ def run_sync():
session_id=task_id,
platform=platform_key,
user_id=source.user_id,
user_name=source.user_name,
chat_id=source.chat_id,
chat_name=source.chat_name,
chat_type=source.chat_type,
thread_id=source.thread_id,
session_db=self._session_db,
fallback_model=self._fallback_model,
)
Expand Down Expand Up @@ -9699,6 +9704,11 @@ def _interim_assistant_cb(text: str, *, already_streamed: bool = False) -> None:
session_id=session_id,
platform=platform_key,
user_id=source.user_id,
user_name=source.user_name,
chat_id=source.chat_id,
chat_name=source.chat_name,
chat_type=source.chat_type,
thread_id=source.thread_id,
gateway_session_key=session_key,
session_db=self._session_db,
fallback_model=self._fallback_model,
Expand Down
7 changes: 5 additions & 2 deletions plugins/memory/hindsight/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,10 @@ Config file: `~/.hermes/hindsight/config.json`
| `retain_async` | `true` | Process retain asynchronously on the Hindsight server |
| `retain_every_n_turns` | `1` | Retain every N turns (1 = every turn) |
| `retain_context` | `conversation between Hermes Agent and the User` | Context label for retained memories |
| `tags` | — | Tags applied when storing memories |
| `retain_tags` | — | Default tags applied to retained memories; merged with per-call tool tags |
| `retain_source` | — | Optional `metadata.source` attached to retained memories |
| `retain_user_prefix` | `User` | Label used before user turns in auto-retained transcripts |
| `retain_assistant_prefix` | `Assistant` | Label used before assistant turns in auto-retained transcripts |

### Integration

Expand Down Expand Up @@ -113,7 +116,7 @@ Available in `hybrid` and `tools` memory modes:

| Tool | Description |
|------|-------------|
| `hindsight_retain` | Store information with auto entity extraction |
| `hindsight_retain` | Store information with auto entity extraction; supports optional per-call `tags` |
| `hindsight_recall` | Multi-strategy search (semantic + entity graph) |
| `hindsight_reflect` | Cross-memory synthesis (LLM-powered) |

Expand Down
235 changes: 198 additions & 37 deletions plugins/memory/hindsight/__init__.py

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions run_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,11 @@ def __init__(
prefill_messages: List[Dict[str, Any]] = None,
platform: str = None,
user_id: str = None,
user_name: str = None,
chat_id: str = None,
chat_name: str = None,
chat_type: str = None,
thread_id: str = None,
gateway_session_key: str = None,
skip_context_files: bool = False,
skip_memory: bool = False,
Expand Down Expand Up @@ -820,6 +825,11 @@ def __init__(
self.ephemeral_system_prompt = ephemeral_system_prompt
self.platform = platform # "cli", "telegram", "discord", "whatsapp", etc.
self._user_id = user_id # Platform user identifier (gateway sessions)
self._user_name = user_name
self._chat_id = chat_id
self._chat_name = chat_name
self._chat_type = chat_type
self._thread_id = thread_id
self._gateway_session_key = gateway_session_key # Stable per-chat key (e.g. agent:main:telegram:dm:123)
# Pluggable print function — CLI replaces this with _cprint so that
# raw ANSI status lines are routed through prompt_toolkit's renderer
Expand Down Expand Up @@ -1471,6 +1481,16 @@ def __init__(
# Thread gateway user identity for per-user memory scoping
if self._user_id:
_init_kwargs["user_id"] = self._user_id
if self._user_name:
_init_kwargs["user_name"] = self._user_name
if self._chat_id:
_init_kwargs["chat_id"] = self._chat_id
if self._chat_name:
_init_kwargs["chat_name"] = self._chat_name
if self._chat_type:
_init_kwargs["chat_type"] = self._chat_type
if self._thread_id:
_init_kwargs["thread_id"] = self._thread_id
# Thread gateway session key for stable per-chat Honcho session isolation
if self._gateway_session_key:
_init_kwargs["gateway_session_key"] = self._gateway_session_key
Expand Down
1 change: 1 addition & 0 deletions scripts/release.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"82637225+kshitijk4poor@users.noreply.github.com": "kshitijk4poor",
"keifergu@tencent.com": "keifergu",
"kshitijk4poor@users.noreply.github.com": "kshitijk4poor",
"abner.the.foreman@agentmail.to": "Abnertheforeman",
"kshitijk4poor@gmail.com": "kshitijk4poor",
"16443023+stablegenius49@users.noreply.github.com": "stablegenius49",
"185121704+stablegenius49@users.noreply.github.com": "stablegenius49",
Expand Down
23 changes: 23 additions & 0 deletions tests/agent/test_memory_user_id.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,28 @@ def test_user_id_forwarded_to_provider(self):
assert p._init_kwargs.get("platform") == "telegram"
assert p._init_session_id == "sess-123"

def test_chat_context_forwarded_to_provider(self):
mgr = MemoryManager()
p = RecordingProvider()
mgr.add_provider(p)

mgr.initialize_all(
session_id="sess-chat",
platform="discord",
user_id="discord_u_7",
user_name="fakeusername",
chat_id="1485316232612941897",
chat_name="fakeassistantname-forums",
chat_type="thread",
thread_id="1491249007475949698",
)

assert p._init_kwargs.get("user_name") == "fakeusername"
assert p._init_kwargs.get("chat_id") == "1485316232612941897"
assert p._init_kwargs.get("chat_name") == "fakeassistantname-forums"
assert p._init_kwargs.get("chat_type") == "thread"
assert p._init_kwargs.get("thread_id") == "1491249007475949698"

def test_no_user_id_when_cli(self):
"""CLI sessions should not have user_id in kwargs."""
mgr = MemoryManager()
Expand Down Expand Up @@ -334,3 +356,4 @@ def test_user_id_none_by_default(self):
agent = object.__new__(AIAgent)
agent._user_id = None
assert agent._user_id is None

Loading
Loading