openclaw-remote 0.4.0 → 0.4.1

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.
Files changed (2) hide show
  1. package/dist/index.js +51 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2800,6 +2800,37 @@ var LEADER_DEBOUNCE_MS = 6e4;
2800
2800
  var leaderRolesCache = [];
2801
2801
  var leaderRolesCacheTime = 0;
2802
2802
  var LEADER_CACHE_TTL = 5 * 6e4;
2803
+ async function resolveAgentIdentity(account, log) {
2804
+ try {
2805
+ const res = await fetch(`${account.baseUrl}/api/v1/roles`, {
2806
+ headers: { Authorization: `Bearer ${account.apiKey}`, Accept: "application/json" },
2807
+ signal: AbortSignal.timeout(1e4)
2808
+ });
2809
+ if (!res.ok) {
2810
+ log?.warn?.(`Failed to resolve agent identity: HTTP ${res.status}`);
2811
+ return null;
2812
+ }
2813
+ const data = await res.json();
2814
+ const roles = data.roles || [];
2815
+ const myRoles = roles.filter((r) => r.is_mine);
2816
+ const myRoleIds = myRoles.map((r) => r.id);
2817
+ const isLeader = myRoles.some((r) => r.is_leader);
2818
+ const hbRes = await fetch(`${account.baseUrl}/api/v1/heartbeat`, {
2819
+ headers: { Authorization: `Bearer ${account.apiKey}`, Accept: "application/json" },
2820
+ signal: AbortSignal.timeout(1e4)
2821
+ });
2822
+ let agentName = "";
2823
+ if (hbRes.ok) {
2824
+ const hb = await hbRes.json();
2825
+ agentName = hb.agent_name || "";
2826
+ }
2827
+ log?.info?.(`Agent identity resolved: "${agentName}", roles: [${myRoleIds.join(", ")}], leader: ${isLeader}`);
2828
+ return { agentName, myRoleIds, isLeader };
2829
+ } catch (err) {
2830
+ log?.warn?.(`Failed to resolve agent identity: ${err}`);
2831
+ return null;
2832
+ }
2833
+ }
2803
2834
  async function fetchLeaderRoles(supabase, log) {
2804
2835
  const now = Date.now();
2805
2836
  if (now - leaderRolesCacheTime < LEADER_CACHE_TTL && leaderRolesCache.length > 0) {
@@ -2824,7 +2855,7 @@ async function fetchLeaderRoles(supabase, log) {
2824
2855
  log?.info?.(`Leader roles cache refreshed: ${leaderRolesCache.length} leader role(s)`);
2825
2856
  return leaderRolesCache;
2826
2857
  }
2827
- function connectRealtime(account, onEvent, onError, log) {
2858
+ function connectRealtime(account, identity, onEvent, onError, log) {
2828
2859
  const { supabaseUrl, supabaseKey } = account;
2829
2860
  if (!supabaseUrl || !supabaseKey) {
2830
2861
  throw new Error("Supabase URL and key are required for Realtime listener. Set supabaseUrl and supabaseKey in channels.remote config.");
@@ -2851,12 +2882,28 @@ function connectRealtime(account, onEvent, onError, log) {
2851
2882
  scheduleLeaderNotification(row.task_id, row.agent_author_id, supabase, log);
2852
2883
  return;
2853
2884
  }
2885
+ const body = row.body || row.content || "";
2886
+ if (!row.author_id && !row.agent_author_id && identity) {
2887
+ if (body.startsWith("\u{1F4CC} Assigned to ")) {
2888
+ const targetName = body.replace("\u{1F4CC} Assigned to ", "").trim();
2889
+ if (targetName.toLowerCase() !== identity.agentName.toLowerCase()) {
2890
+ log?.info?.(`Skipping assignment notification for ${targetName} (I am ${identity.agentName})`);
2891
+ return;
2892
+ }
2893
+ }
2894
+ if (body.startsWith("\u{1F440} ")) {
2895
+ if (!identity.isLeader) {
2896
+ log?.info?.(`Skipping leader notification (I am not a leader)`);
2897
+ return;
2898
+ }
2899
+ }
2900
+ }
2854
2901
  const event = {
2855
2902
  type: "task.commented",
2856
2903
  task_id: row.task_id,
2857
2904
  comment: {
2858
2905
  id: row.id,
2859
- content: row.body || row.content || "",
2906
+ content: body,
2860
2907
  author_name: row.author_name || "System",
2861
2908
  author_id: row.author_id || "",
2862
2909
  created_at: row.created_at
@@ -3231,8 +3278,10 @@ function createRemotePlugin() {
3231
3278
  let realtimeHandle = null;
3232
3279
  if (account.supabaseUrl && account.supabaseKey) {
3233
3280
  try {
3281
+ const identity = await resolveAgentIdentity(account, log);
3234
3282
  realtimeHandle = connectRealtime(
3235
3283
  account,
3284
+ identity,
3236
3285
  async (event) => {
3237
3286
  const formatted = formatEvent(event);
3238
3287
  if (!formatted) return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclaw-remote",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Remote project board channel plugin for OpenClaw",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",