feat: support multi-user Discord threads via context var
- Add contextvars.ContextVar to carry resolved peer name from pre_gateway_dispatch to Honcho session init without modifying event.user_id (auth uses raw Discord snowflake) - _pre_gateway_dispatch: now stores resolved peer in context var - _patched_do_session_init: reads context var first, falls back to kanban resolution, then to existing user_id Requires thread_sessions_per_user: true in profile config.yaml (added to ashley, claire, finn, matt, paul)
This commit is contained in:
33
__init__.py
33
__init__.py
@@ -10,6 +10,7 @@ Config: /opt/data/identity-config.json (persistent volume)
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import contextvars
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
@@ -23,6 +24,12 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
CONFIG_PATH = Path("/opt/data/identity-config.json")
|
CONFIG_PATH = Path("/opt/data/identity-config.json")
|
||||||
|
|
||||||
|
# Context var to carry resolved peer name from pre_gateway_dispatch
|
||||||
|
# to Honcho's _do_session_init without modifying event.user_id.
|
||||||
|
_resolved_peer_var: contextvars.ContextVar[str | None] = contextvars.ContextVar(
|
||||||
|
"identity_resolved_peer", default=None
|
||||||
|
)
|
||||||
|
|
||||||
# ── Config ──────────────────────────────────────────────────────────────────
|
# ── Config ──────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
||||||
@@ -161,10 +168,22 @@ _original_init: Callable | None = None
|
|||||||
def _patched_do_session_init(self, cfg, session_id: str, **kwargs):
|
def _patched_do_session_init(self, cfg, session_id: str, **kwargs):
|
||||||
"""Wrapper around Honcho's _do_session_init.
|
"""Wrapper around Honcho's _do_session_init.
|
||||||
|
|
||||||
If no user_id was provided by the gateway (kanban worker / CLI context),
|
Priority for user_id:
|
||||||
resolve one from the identity config and inject it.
|
1. _resolved_peer_var from pre_gateway_dispatch (gateway multi-user)
|
||||||
|
2. get_peer_name() for kanban workers
|
||||||
|
3. kwargs.get("user_id") as-is (existing Discord snowflake fallback)
|
||||||
"""
|
"""
|
||||||
if not kwargs.get("user_id"):
|
# Check context var first (set by _pre_gateway_dispatch for
|
||||||
|
# gateway-originated messages — peer name already resolved)
|
||||||
|
resolved = _resolved_peer_var.get()
|
||||||
|
if resolved:
|
||||||
|
logger.info(
|
||||||
|
"identity: Honcho peer '%s' from gateway dispatch (was %s)",
|
||||||
|
resolved, kwargs.get("user_id", "(none)"),
|
||||||
|
)
|
||||||
|
kwargs["user_id"] = resolved
|
||||||
|
elif not kwargs.get("user_id"):
|
||||||
|
# Kanban worker / CLI — no user_id set by gateway
|
||||||
resolved = get_peer_name()
|
resolved = get_peer_name()
|
||||||
if resolved:
|
if resolved:
|
||||||
logger.info(
|
logger.info(
|
||||||
@@ -222,13 +241,17 @@ def _apply_honcho_patch():
|
|||||||
|
|
||||||
|
|
||||||
def _pre_gateway_dispatch(event: Any, gateway: Any, session_store: Any, **kw) -> dict | None:
|
def _pre_gateway_dispatch(event: Any, gateway: Any, session_store: Any, **kw) -> dict | None:
|
||||||
"""Log resolved peer identity before dispatch."""
|
"""Resolve peer identity and store it for Honcho session init."""
|
||||||
platform = getattr(event, "platform", "unknown")
|
platform = getattr(event, "platform", "unknown")
|
||||||
user_id = getattr(event, "user_id", "unknown")
|
user_id = getattr(event, "user_id", "unknown")
|
||||||
resolved = resolve_peer(platform, user_id)
|
resolved = resolve_peer(platform, user_id)
|
||||||
|
|
||||||
if resolved:
|
if resolved:
|
||||||
logger.debug("identity: gateway platform=%s user_id=%s → peer=%s", platform, user_id, resolved)
|
logger.debug(
|
||||||
|
"identity: gateway platform=%s user_id=%s → peer=%s",
|
||||||
|
platform, user_id, resolved,
|
||||||
|
)
|
||||||
|
_resolved_peer_var.set(resolved)
|
||||||
else:
|
else:
|
||||||
logger.info("identity: unmapped gateway user platform=%s user_id=%s", platform, user_id)
|
logger.info("identity: unmapped gateway user platform=%s user_id=%s", platform, user_id)
|
||||||
return None
|
return None
|
||||||
|
|||||||
Reference in New Issue
Block a user