@misterhuydo/sentinel 1.0.87 → 1.0.89
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.cairn/.hint-lock
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2026-03-
|
|
1
|
+
2026-03-23T06:03:48.001Z
|
package/.cairn/session.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"message": "Auto-checkpoint at 2026-03-
|
|
3
|
-
"checkpoint_at": "2026-03-
|
|
2
|
+
"message": "Auto-checkpoint at 2026-03-23T06:04:44.021Z",
|
|
3
|
+
"checkpoint_at": "2026-03-23T06:04:44.022Z",
|
|
4
4
|
"active_files": [],
|
|
5
5
|
"notes": [],
|
|
6
6
|
"mtime_snapshot": {}
|
package/package.json
CHANGED
|
@@ -1435,9 +1435,15 @@ async def _handle_with_cli(
|
|
|
1435
1435
|
)
|
|
1436
1436
|
history_text += f"\n{role}: {content}"
|
|
1437
1437
|
|
|
1438
|
+
slack_mention = f"<@{user_id}>" if user_id else (user_name or "")
|
|
1439
|
+
known_users = store.get_all_users()
|
|
1440
|
+
users_hint = ", ".join(f"<@{uid}> = {name}" for uid, name in known_users.items())
|
|
1438
1441
|
prompt = (
|
|
1439
1442
|
_SYSTEM
|
|
1440
|
-
+ (f"\nYou are speaking with: {user_name}" if user_name else "")
|
|
1443
|
+
+ (f"\nYou are speaking with: {user_name} (Slack mention: {slack_mention})" if user_name else "")
|
|
1444
|
+
+ "\nAlways start your reply by addressing the user directly using their Slack mention, e.g. \"<@U123> here is what I found...\"."
|
|
1445
|
+
+ " Never use their plain name — always use the <@USER_ID> format so Slack highlights it."
|
|
1446
|
+
+ (f"\nKnown Slack users: {users_hint}" if users_hint else "")
|
|
1441
1447
|
+ f"\n\nCurrent time: {ts}"
|
|
1442
1448
|
+ f"\nSentinel status: {'⏸ PAUSED' if paused else '▶ RUNNING'}"
|
|
1443
1449
|
+ f"\nManaged repos: {', '.join(repos) if repos else '(none configured)'}"
|
|
@@ -1532,9 +1538,15 @@ async def _handle_with_api(
|
|
|
1532
1538
|
ts = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M UTC")
|
|
1533
1539
|
known_projects = [_read_project_name(d) for d in _find_project_dirs()]
|
|
1534
1540
|
log_sources = list(cfg_loader.log_sources.keys())
|
|
1541
|
+
slack_mention = f"<@{user_id}>" if user_id else (user_name or "")
|
|
1542
|
+
known_users = store.get_all_users() # {user_id: display_name}
|
|
1543
|
+
users_hint = ", ".join(f"<@{uid}> = {name}" for uid, name in known_users.items())
|
|
1535
1544
|
system = (
|
|
1536
1545
|
_SYSTEM
|
|
1537
|
-
+ (f"\nYou are speaking with: {user_name}" if user_name else "")
|
|
1546
|
+
+ (f"\nYou are speaking with: {user_name} (Slack mention: {slack_mention})" if user_name else "")
|
|
1547
|
+
+ "\nAlways start your reply by addressing the user directly using their Slack mention, e.g. \"<@U123> here is what I found...\"."
|
|
1548
|
+
+ " Never use their plain name — always use the <@USER_ID> format so Slack highlights it."
|
|
1549
|
+
+ (f"\nKnown Slack users: {users_hint}" if users_hint else "")
|
|
1538
1550
|
+ f"\n\nCurrent time: {ts}"
|
|
1539
1551
|
+ f"\nSentinel status: {'⏸ PAUSED' if paused else '▶ RUNNING'}"
|
|
1540
1552
|
+ f"\nManaged repos: {', '.join(repos) if repos else '(none configured)'}"
|
|
@@ -342,6 +342,7 @@ async def _dispatch(event: dict, client, cfg_loader, store) -> None:
|
|
|
342
342
|
return
|
|
343
343
|
|
|
344
344
|
user_name = await _resolve_name(client, user_id)
|
|
345
|
+
store.upsert_user(user_id, user_name)
|
|
345
346
|
session = await _get_or_create_session(user_id, user_name, channel)
|
|
346
347
|
|
|
347
348
|
if session.busy:
|
|
@@ -391,6 +391,43 @@ class StateStore:
|
|
|
391
391
|
).fetchall()
|
|
392
392
|
return [dict(r) for r in rows]
|
|
393
393
|
|
|
394
|
+
def upsert_user(self, user_id: str, display_name: str) -> None:
|
|
395
|
+
"""Store or update the display name for a Slack user ID."""
|
|
396
|
+
with self._conn() as conn:
|
|
397
|
+
conn.execute(
|
|
398
|
+
"CREATE TABLE IF NOT EXISTS slack_users "
|
|
399
|
+
"(user_id TEXT PRIMARY KEY, display_name TEXT, updated_at TEXT)"
|
|
400
|
+
)
|
|
401
|
+
conn.execute(
|
|
402
|
+
"INSERT OR REPLACE INTO slack_users (user_id, display_name, updated_at) "
|
|
403
|
+
"VALUES (?, ?, ?)",
|
|
404
|
+
(user_id, display_name, _now()),
|
|
405
|
+
)
|
|
406
|
+
|
|
407
|
+
def get_user_name(self, user_id: str) -> str:
|
|
408
|
+
"""Return the stored display name for a user ID, or the ID itself if unknown."""
|
|
409
|
+
with self._conn() as conn:
|
|
410
|
+
conn.execute(
|
|
411
|
+
"CREATE TABLE IF NOT EXISTS slack_users "
|
|
412
|
+
"(user_id TEXT PRIMARY KEY, display_name TEXT, updated_at TEXT)"
|
|
413
|
+
)
|
|
414
|
+
row = conn.execute(
|
|
415
|
+
"SELECT display_name FROM slack_users WHERE user_id = ?", (user_id,)
|
|
416
|
+
).fetchone()
|
|
417
|
+
return row[0] if row else user_id
|
|
418
|
+
|
|
419
|
+
def get_all_users(self) -> dict[str, str]:
|
|
420
|
+
"""Return all known {user_id: display_name} mappings."""
|
|
421
|
+
with self._conn() as conn:
|
|
422
|
+
conn.execute(
|
|
423
|
+
"CREATE TABLE IF NOT EXISTS slack_users "
|
|
424
|
+
"(user_id TEXT PRIMARY KEY, display_name TEXT, updated_at TEXT)"
|
|
425
|
+
)
|
|
426
|
+
rows = conn.execute(
|
|
427
|
+
"SELECT user_id, display_name FROM slack_users ORDER BY display_name"
|
|
428
|
+
).fetchall()
|
|
429
|
+
return {r[0]: r[1] for r in rows}
|
|
430
|
+
|
|
394
431
|
def save_conversation(self, user_id: str, history: list):
|
|
395
432
|
"""Persist the last N messages of a user conversation to SQLite."""
|
|
396
433
|
trimmed = history[-self._MAX_HISTORY_MESSAGES:]
|