@alfe.ai/openclaw-chat 0.0.28 → 0.0.29

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/dist/plugin.d.cts CHANGED
@@ -220,6 +220,12 @@ interface AgentEventPayload {
220
220
  data: Record<string, unknown>;
221
221
  sessionKey?: string;
222
222
  }
223
+ interface PluginServiceContext {
224
+ config: Record<string, unknown>;
225
+ workspaceDir?: string;
226
+ stateDir: string;
227
+ logger: PluginLogger;
228
+ }
223
229
  interface PluginApi {
224
230
  logger: PluginLogger;
225
231
  registrationMode?: 'full' | 'setup-only' | 'setup-runtime' | 'cli-metadata';
@@ -234,6 +240,11 @@ interface PluginApi {
234
240
  execute: (toolCallId: string, params: Record<string, unknown>) => Promise<unknown>;
235
241
  }): void;
236
242
  registerGatewayMethod?(name: string, handler: (...args: unknown[]) => Promise<unknown>): void;
243
+ registerService?(service: {
244
+ id: string;
245
+ start: (ctx: PluginServiceContext) => void | Promise<void>;
246
+ stop?: (ctx: PluginServiceContext) => void | Promise<void>;
247
+ }): void;
237
248
  on(event: string, handler: (...args: unknown[]) => void | Promise<void>, options?: {
238
249
  priority?: number;
239
250
  }): void;
package/dist/plugin.d.ts CHANGED
@@ -220,6 +220,12 @@ interface AgentEventPayload {
220
220
  data: Record<string, unknown>;
221
221
  sessionKey?: string;
222
222
  }
223
+ interface PluginServiceContext {
224
+ config: Record<string, unknown>;
225
+ workspaceDir?: string;
226
+ stateDir: string;
227
+ logger: PluginLogger;
228
+ }
223
229
  interface PluginApi {
224
230
  logger: PluginLogger;
225
231
  registrationMode?: 'full' | 'setup-only' | 'setup-runtime' | 'cli-metadata';
@@ -234,6 +240,11 @@ interface PluginApi {
234
240
  execute: (toolCallId: string, params: Record<string, unknown>) => Promise<unknown>;
235
241
  }): void;
236
242
  registerGatewayMethod?(name: string, handler: (...args: unknown[]) => Promise<unknown>): void;
243
+ registerService?(service: {
244
+ id: string;
245
+ start: (ctx: PluginServiceContext) => void | Promise<void>;
246
+ stop?: (ctx: PluginServiceContext) => void | Promise<void>;
247
+ }): void;
237
248
  on(event: string, handler: (...args: unknown[]) => void | Promise<void>, options?: {
238
249
  priority?: number;
239
250
  }): void;
package/dist/plugin2.cjs CHANGED
@@ -814,9 +814,13 @@ const plugin = {
814
814
  const alfeChannel = createAlfeChannelPlugin();
815
815
  api.registerChannel(alfeChannel);
816
816
  log.info(`Registered channel: ${alfeChannel.id}`);
817
- if (api.registrationMode && api.registrationMode !== "full") return;
818
- globalThis.__alfeChatPluginActivated = true;
819
- if (!alreadyActivated) {
817
+ const pluginConfig = (((api.config ?? {}).plugins?.entries)?.["@alfe.ai/openclaw-chat"] ?? {}).config ?? {};
818
+ const startChatService = () => {
819
+ if (globalThis.__alfeChatPluginActivated === true) {
820
+ log.debug("Chat plugin already activated — skipping duplicate");
821
+ return;
822
+ }
823
+ globalThis.__alfeChatPluginActivated = true;
820
824
  log.info("Chat plugin registering...");
821
825
  resolveOpenClawSdk(log);
822
826
  pluginRuntime = api.runtime ?? null;
@@ -829,44 +833,88 @@ const plugin = {
829
833
  } catch {
830
834
  log.debug("Metrics client not initialized — activity tracking disabled");
831
835
  }
832
- }
833
- const pluginConfig = (((api.config ?? {}).plugins?.entries)?.["@alfe.ai/openclaw-chat"] ?? {}).config ?? {};
834
- if (!alreadyActivated) connectingPromise = Promise.resolve().then(() => {
835
- try {
836
- const { apiKey, chatWsUrl } = (0, _alfe_ai_chat.resolveAlfeChat)({
837
- apiKey: pluginConfig.apiKey,
838
- chatWsUrl: pluginConfig.chatWsUrl
839
- });
840
- if (chatWsUrl && apiKey) {
841
- log.info(`Connecting to chat service: ${chatWsUrl}`);
842
- chatClient = new _alfe_ai_chat.ChatServiceClient({
843
- wsUrl: chatWsUrl,
844
- apiKey,
845
- onRequest: (request) => {
846
- const handle = async () => {
847
- if (request.method === "agent") await handleAgentRequest(request, log);
848
- else if (request.method === "sessions.list") await handleSessionsList(request, log);
849
- else if (request.method === "sessions.get") await handleSessionsGet(request, log);
850
- else chatClient?.sendResponse(request.id, false, { message: `Unknown method: ${request.method}` });
851
- };
852
- handle().catch((err) => {
853
- const errMsg = err instanceof Error ? err.message : String(err);
854
- log.error(`Request handler crashed: ${errMsg}`);
855
- chatClient?.sendResponse(request.id, false, { message: "Internal error" });
856
- });
857
- },
858
- onConnectionChange: (connected) => {
859
- log.info(`Chat service connection: ${connected ? "connected" : "disconnected"}`);
860
- },
861
- logger: log
836
+ connectingPromise = Promise.resolve().then(() => {
837
+ try {
838
+ const { apiKey, chatWsUrl } = (0, _alfe_ai_chat.resolveAlfeChat)({
839
+ apiKey: pluginConfig.apiKey,
840
+ chatWsUrl: pluginConfig.chatWsUrl
862
841
  });
863
- chatClient.start();
864
- log.info("Chat service relay started");
865
- } else log.info("Chat service URL not configured — running without chat service relay");
866
- } catch (err) {
867
- log.error(`Failed to initialize chat service: ${err instanceof Error ? err.message : String(err)}`);
842
+ if (chatWsUrl && apiKey) {
843
+ log.info(`Connecting to chat service: ${chatWsUrl}`);
844
+ chatClient = new _alfe_ai_chat.ChatServiceClient({
845
+ wsUrl: chatWsUrl,
846
+ apiKey,
847
+ onRequest: (request) => {
848
+ const handle = async () => {
849
+ if (request.method === "agent") await handleAgentRequest(request, log);
850
+ else if (request.method === "sessions.list") await handleSessionsList(request, log);
851
+ else if (request.method === "sessions.get") await handleSessionsGet(request, log);
852
+ else chatClient?.sendResponse(request.id, false, { message: `Unknown method: ${request.method}` });
853
+ };
854
+ handle().catch((err) => {
855
+ const errMsg = err instanceof Error ? err.message : String(err);
856
+ log.error(`Request handler crashed: ${errMsg}`);
857
+ chatClient?.sendResponse(request.id, false, { message: "Internal error" });
858
+ });
859
+ },
860
+ onConnectionChange: (connected) => {
861
+ log.info(`Chat service connection: ${connected ? "connected" : "disconnected"}`);
862
+ },
863
+ logger: log
864
+ });
865
+ chatClient.start();
866
+ log.info("Chat service relay started");
867
+ } else log.info("Chat service URL not configured — running without chat service relay");
868
+ } catch (err) {
869
+ log.error(`Failed to initialize chat service: ${err instanceof Error ? err.message : String(err)}`);
870
+ }
871
+ });
872
+ if (typeof api.registerTool === "function") connectingPromise.then(() => {
873
+ if (chatClient && typeof api.registerTool === "function") {
874
+ const a2aTools = buildA2ATools(chatClient, log);
875
+ for (const tool of a2aTools) api.registerTool(tool);
876
+ log.info(`Registered ${String(a2aTools.length)} agent-to-agent tools`);
877
+ }
878
+ }).catch(() => {});
879
+ api.on("session_start", async (...eventArgs) => {
880
+ if (!pluginRuntime) return;
881
+ const key = eventArgs[0].sessionKey;
882
+ if (!key || isAlfeSessionKey(key)) return;
883
+ log.info(`Chat session starting: ${key}`);
884
+ await createSession(key, "", "alfe");
885
+ }, { priority: 50 });
886
+ api.on("message_received", async (...eventArgs) => {
887
+ if (!pluginRuntime) return;
888
+ const event = eventArgs[0];
889
+ const ctx = eventArgs[1];
890
+ if (!ctx.conversationId || ctx.channelId === "alfe") return;
891
+ await addMessage(ctx.conversationId, "user", event.content, event.from);
892
+ });
893
+ api.on("session_end", (...eventArgs) => {
894
+ if (!pluginRuntime) return;
895
+ const key = eventArgs[0].sessionKey;
896
+ if (!key || !isAlfeSessionKey(key)) return;
897
+ log.info(`Chat session ending: ${key}`);
898
+ });
899
+ };
900
+ const stopChatService = async () => {
901
+ globalThis.__alfeChatPluginActivated = false;
902
+ if (connectingPromise) {
903
+ await connectingPromise.catch((err) => {
904
+ log.debug(`Connection attempt failed: ${err instanceof Error ? err.message : String(err)}`);
905
+ });
906
+ connectingPromise = null;
868
907
  }
869
- });
908
+ if (chatClient) {
909
+ chatClient.stop();
910
+ chatClient = null;
911
+ log.info("Chat service client stopped");
912
+ }
913
+ pluginRuntime = null;
914
+ dispatchInbound = null;
915
+ metricsClient = null;
916
+ log.info("Chat plugin deactivated");
917
+ };
870
918
  if (typeof api.registerGatewayMethod === "function") {
871
919
  api.registerGatewayMethod("sessions.list", async (...args) => {
872
920
  const params = args[0];
@@ -902,35 +950,16 @@ const plugin = {
902
950
  });
903
951
  log.info("Registered gateway RPC methods: sessions.list, sessions.get");
904
952
  }
905
- if (!alreadyActivated && typeof api.registerTool === "function") connectingPromise?.then(() => {
906
- if (chatClient && typeof api.registerTool === "function") {
907
- const a2aTools = buildA2ATools(chatClient, log);
908
- for (const tool of a2aTools) api.registerTool(tool);
909
- log.info(`Registered ${String(a2aTools.length)} agent-to-agent tools`);
953
+ if (api.registerService) api.registerService({
954
+ id: "alfe-chat-relay",
955
+ start: () => {
956
+ startChatService();
957
+ },
958
+ stop: async () => {
959
+ await stopChatService();
910
960
  }
911
- }).catch(() => {});
912
- if (!alreadyActivated) {
913
- api.on("session_start", async (...eventArgs) => {
914
- if (!pluginRuntime) return;
915
- const key = eventArgs[0].sessionKey;
916
- if (!key || isAlfeSessionKey(key)) return;
917
- log.info(`Chat session starting: ${key}`);
918
- await createSession(key, "", "alfe");
919
- }, { priority: 50 });
920
- api.on("message_received", async (...eventArgs) => {
921
- if (!pluginRuntime) return;
922
- const event = eventArgs[0];
923
- const ctx = eventArgs[1];
924
- if (!ctx.conversationId || ctx.channelId === "alfe") return;
925
- await addMessage(ctx.conversationId, "user", event.content, event.from);
926
- });
927
- api.on("session_end", (...eventArgs) => {
928
- if (!pluginRuntime) return;
929
- const key = eventArgs[0].sessionKey;
930
- if (!key || !isAlfeSessionKey(key)) return;
931
- log.info(`Chat session ending: ${key}`);
932
- });
933
- }
961
+ });
962
+ else if (!alreadyActivated) startChatService();
934
963
  log.info("Chat plugin registered");
935
964
  },
936
965
  async deactivate(api) {
package/dist/plugin2.js CHANGED
@@ -817,9 +817,13 @@ const plugin = {
817
817
  const alfeChannel = createAlfeChannelPlugin();
818
818
  api.registerChannel(alfeChannel);
819
819
  log.info(`Registered channel: ${alfeChannel.id}`);
820
- if (api.registrationMode && api.registrationMode !== "full") return;
821
- globalThis.__alfeChatPluginActivated = true;
822
- if (!alreadyActivated) {
820
+ const pluginConfig = (((api.config ?? {}).plugins?.entries)?.["@alfe.ai/openclaw-chat"] ?? {}).config ?? {};
821
+ const startChatService = () => {
822
+ if (globalThis.__alfeChatPluginActivated === true) {
823
+ log.debug("Chat plugin already activated — skipping duplicate");
824
+ return;
825
+ }
826
+ globalThis.__alfeChatPluginActivated = true;
823
827
  log.info("Chat plugin registering...");
824
828
  resolveOpenClawSdk(log);
825
829
  pluginRuntime = api.runtime ?? null;
@@ -832,44 +836,88 @@ const plugin = {
832
836
  } catch {
833
837
  log.debug("Metrics client not initialized — activity tracking disabled");
834
838
  }
835
- }
836
- const pluginConfig = (((api.config ?? {}).plugins?.entries)?.["@alfe.ai/openclaw-chat"] ?? {}).config ?? {};
837
- if (!alreadyActivated) connectingPromise = Promise.resolve().then(() => {
838
- try {
839
- const { apiKey, chatWsUrl } = resolveAlfeChat({
840
- apiKey: pluginConfig.apiKey,
841
- chatWsUrl: pluginConfig.chatWsUrl
842
- });
843
- if (chatWsUrl && apiKey) {
844
- log.info(`Connecting to chat service: ${chatWsUrl}`);
845
- chatClient = new ChatServiceClient({
846
- wsUrl: chatWsUrl,
847
- apiKey,
848
- onRequest: (request) => {
849
- const handle = async () => {
850
- if (request.method === "agent") await handleAgentRequest(request, log);
851
- else if (request.method === "sessions.list") await handleSessionsList(request, log);
852
- else if (request.method === "sessions.get") await handleSessionsGet(request, log);
853
- else chatClient?.sendResponse(request.id, false, { message: `Unknown method: ${request.method}` });
854
- };
855
- handle().catch((err) => {
856
- const errMsg = err instanceof Error ? err.message : String(err);
857
- log.error(`Request handler crashed: ${errMsg}`);
858
- chatClient?.sendResponse(request.id, false, { message: "Internal error" });
859
- });
860
- },
861
- onConnectionChange: (connected) => {
862
- log.info(`Chat service connection: ${connected ? "connected" : "disconnected"}`);
863
- },
864
- logger: log
839
+ connectingPromise = Promise.resolve().then(() => {
840
+ try {
841
+ const { apiKey, chatWsUrl } = resolveAlfeChat({
842
+ apiKey: pluginConfig.apiKey,
843
+ chatWsUrl: pluginConfig.chatWsUrl
865
844
  });
866
- chatClient.start();
867
- log.info("Chat service relay started");
868
- } else log.info("Chat service URL not configured — running without chat service relay");
869
- } catch (err) {
870
- log.error(`Failed to initialize chat service: ${err instanceof Error ? err.message : String(err)}`);
845
+ if (chatWsUrl && apiKey) {
846
+ log.info(`Connecting to chat service: ${chatWsUrl}`);
847
+ chatClient = new ChatServiceClient({
848
+ wsUrl: chatWsUrl,
849
+ apiKey,
850
+ onRequest: (request) => {
851
+ const handle = async () => {
852
+ if (request.method === "agent") await handleAgentRequest(request, log);
853
+ else if (request.method === "sessions.list") await handleSessionsList(request, log);
854
+ else if (request.method === "sessions.get") await handleSessionsGet(request, log);
855
+ else chatClient?.sendResponse(request.id, false, { message: `Unknown method: ${request.method}` });
856
+ };
857
+ handle().catch((err) => {
858
+ const errMsg = err instanceof Error ? err.message : String(err);
859
+ log.error(`Request handler crashed: ${errMsg}`);
860
+ chatClient?.sendResponse(request.id, false, { message: "Internal error" });
861
+ });
862
+ },
863
+ onConnectionChange: (connected) => {
864
+ log.info(`Chat service connection: ${connected ? "connected" : "disconnected"}`);
865
+ },
866
+ logger: log
867
+ });
868
+ chatClient.start();
869
+ log.info("Chat service relay started");
870
+ } else log.info("Chat service URL not configured — running without chat service relay");
871
+ } catch (err) {
872
+ log.error(`Failed to initialize chat service: ${err instanceof Error ? err.message : String(err)}`);
873
+ }
874
+ });
875
+ if (typeof api.registerTool === "function") connectingPromise.then(() => {
876
+ if (chatClient && typeof api.registerTool === "function") {
877
+ const a2aTools = buildA2ATools(chatClient, log);
878
+ for (const tool of a2aTools) api.registerTool(tool);
879
+ log.info(`Registered ${String(a2aTools.length)} agent-to-agent tools`);
880
+ }
881
+ }).catch(() => {});
882
+ api.on("session_start", async (...eventArgs) => {
883
+ if (!pluginRuntime) return;
884
+ const key = eventArgs[0].sessionKey;
885
+ if (!key || isAlfeSessionKey(key)) return;
886
+ log.info(`Chat session starting: ${key}`);
887
+ await createSession(key, "", "alfe");
888
+ }, { priority: 50 });
889
+ api.on("message_received", async (...eventArgs) => {
890
+ if (!pluginRuntime) return;
891
+ const event = eventArgs[0];
892
+ const ctx = eventArgs[1];
893
+ if (!ctx.conversationId || ctx.channelId === "alfe") return;
894
+ await addMessage(ctx.conversationId, "user", event.content, event.from);
895
+ });
896
+ api.on("session_end", (...eventArgs) => {
897
+ if (!pluginRuntime) return;
898
+ const key = eventArgs[0].sessionKey;
899
+ if (!key || !isAlfeSessionKey(key)) return;
900
+ log.info(`Chat session ending: ${key}`);
901
+ });
902
+ };
903
+ const stopChatService = async () => {
904
+ globalThis.__alfeChatPluginActivated = false;
905
+ if (connectingPromise) {
906
+ await connectingPromise.catch((err) => {
907
+ log.debug(`Connection attempt failed: ${err instanceof Error ? err.message : String(err)}`);
908
+ });
909
+ connectingPromise = null;
871
910
  }
872
- });
911
+ if (chatClient) {
912
+ chatClient.stop();
913
+ chatClient = null;
914
+ log.info("Chat service client stopped");
915
+ }
916
+ pluginRuntime = null;
917
+ dispatchInbound = null;
918
+ metricsClient = null;
919
+ log.info("Chat plugin deactivated");
920
+ };
873
921
  if (typeof api.registerGatewayMethod === "function") {
874
922
  api.registerGatewayMethod("sessions.list", async (...args) => {
875
923
  const params = args[0];
@@ -905,35 +953,16 @@ const plugin = {
905
953
  });
906
954
  log.info("Registered gateway RPC methods: sessions.list, sessions.get");
907
955
  }
908
- if (!alreadyActivated && typeof api.registerTool === "function") connectingPromise?.then(() => {
909
- if (chatClient && typeof api.registerTool === "function") {
910
- const a2aTools = buildA2ATools(chatClient, log);
911
- for (const tool of a2aTools) api.registerTool(tool);
912
- log.info(`Registered ${String(a2aTools.length)} agent-to-agent tools`);
956
+ if (api.registerService) api.registerService({
957
+ id: "alfe-chat-relay",
958
+ start: () => {
959
+ startChatService();
960
+ },
961
+ stop: async () => {
962
+ await stopChatService();
913
963
  }
914
- }).catch(() => {});
915
- if (!alreadyActivated) {
916
- api.on("session_start", async (...eventArgs) => {
917
- if (!pluginRuntime) return;
918
- const key = eventArgs[0].sessionKey;
919
- if (!key || isAlfeSessionKey(key)) return;
920
- log.info(`Chat session starting: ${key}`);
921
- await createSession(key, "", "alfe");
922
- }, { priority: 50 });
923
- api.on("message_received", async (...eventArgs) => {
924
- if (!pluginRuntime) return;
925
- const event = eventArgs[0];
926
- const ctx = eventArgs[1];
927
- if (!ctx.conversationId || ctx.channelId === "alfe") return;
928
- await addMessage(ctx.conversationId, "user", event.content, event.from);
929
- });
930
- api.on("session_end", (...eventArgs) => {
931
- if (!pluginRuntime) return;
932
- const key = eventArgs[0].sessionKey;
933
- if (!key || !isAlfeSessionKey(key)) return;
934
- log.info(`Chat session ending: ${key}`);
935
- });
936
- }
964
+ });
965
+ else if (!alreadyActivated) startChatService();
937
966
  log.info("Chat plugin registered");
938
967
  },
939
968
  async deactivate(api) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfe.ai/openclaw-chat",
3
- "version": "0.0.28",
3
+ "version": "0.0.29",
4
4
  "description": "OpenClaw chat plugin for Alfe — web widget and mobile app channels",
5
5
  "type": "module",
6
6
  "main": "./dist/plugin.js",