@alfe.ai/openclaw 0.4.13 → 0.4.14

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/index.cjs CHANGED
@@ -3749,13 +3749,42 @@ require_websocket_server();
3749
3749
  var wrapper_default = import_websocket.default;
3750
3750
  //#endregion
3751
3751
  //#region ../../packages-internal/agent-client/dist/chat-event-bus.js
3752
+ const defaultLogger$1 = { warn: (msg, ...args) => {
3753
+ console.warn(msg, ...args);
3754
+ } };
3752
3755
  var ChatEventBus = class extends node_events.EventEmitter {
3753
- constructor() {
3756
+ logger;
3757
+ constructor(logger = defaultLogger$1) {
3754
3758
  super();
3759
+ this.logger = logger;
3755
3760
  this.setMaxListeners(100);
3756
3761
  }
3762
+ /**
3763
+ * Fan a delta out to every subscriber, ISOLATING each one.
3764
+ *
3765
+ * `EventEmitter.emit` invokes listeners synchronously and lets the first
3766
+ * throw escape, so one bad subscriber both skips every later subscriber and
3767
+ * unwinds the caller. That matters here because callers do real work either
3768
+ * side of this: `daemon-server.handleDaemonMessage` emits BEFORE its timeout
3769
+ * bookkeeping (so a delta is never lost to a bookkeeping bug), which means an
3770
+ * unisolated throw would skip the bookkeeping instead — the inactivity window
3771
+ * would stop being extended and a healthy streaming turn would die at its
3772
+ * deadline. Isolation makes that ordering safe in both directions: a broken
3773
+ * subscriber can only break itself.
3774
+ *
3775
+ * `rawListeners` (not `listeners`) so a `once` subscriber still unregisters —
3776
+ * `listeners` unwraps the one-shot wrapper and would leave it subscribed.
3777
+ */
3757
3778
  emitChat(payload) {
3758
- this.emit("chat", payload);
3779
+ for (const listener of this.rawListeners("chat")) try {
3780
+ listener.call(this, payload);
3781
+ } catch (err) {
3782
+ this.logger.warn("chat-event-bus listener threw; continuing fan-out", {
3783
+ sessionKey: payload.sessionKey,
3784
+ errName: err instanceof Error ? err.name : typeof err,
3785
+ metric: "chat.event_bus.listener_failed"
3786
+ });
3787
+ }
3759
3788
  }
3760
3789
  onSession(sessionKey, handler) {
3761
3790
  const filtered = (payload) => {
package/dist/index.js CHANGED
@@ -3748,13 +3748,42 @@ require_websocket_server();
3748
3748
  var wrapper_default = import_websocket.default;
3749
3749
  //#endregion
3750
3750
  //#region ../../packages-internal/agent-client/dist/chat-event-bus.js
3751
+ const defaultLogger$1 = { warn: (msg, ...args) => {
3752
+ console.warn(msg, ...args);
3753
+ } };
3751
3754
  var ChatEventBus = class extends EventEmitter {
3752
- constructor() {
3755
+ logger;
3756
+ constructor(logger = defaultLogger$1) {
3753
3757
  super();
3758
+ this.logger = logger;
3754
3759
  this.setMaxListeners(100);
3755
3760
  }
3761
+ /**
3762
+ * Fan a delta out to every subscriber, ISOLATING each one.
3763
+ *
3764
+ * `EventEmitter.emit` invokes listeners synchronously and lets the first
3765
+ * throw escape, so one bad subscriber both skips every later subscriber and
3766
+ * unwinds the caller. That matters here because callers do real work either
3767
+ * side of this: `daemon-server.handleDaemonMessage` emits BEFORE its timeout
3768
+ * bookkeeping (so a delta is never lost to a bookkeeping bug), which means an
3769
+ * unisolated throw would skip the bookkeeping instead — the inactivity window
3770
+ * would stop being extended and a healthy streaming turn would die at its
3771
+ * deadline. Isolation makes that ordering safe in both directions: a broken
3772
+ * subscriber can only break itself.
3773
+ *
3774
+ * `rawListeners` (not `listeners`) so a `once` subscriber still unregisters —
3775
+ * `listeners` unwraps the one-shot wrapper and would leave it subscribed.
3776
+ */
3756
3777
  emitChat(payload) {
3757
- this.emit("chat", payload);
3778
+ for (const listener of this.rawListeners("chat")) try {
3779
+ listener.call(this, payload);
3780
+ } catch (err) {
3781
+ this.logger.warn("chat-event-bus listener threw; continuing fan-out", {
3782
+ sessionKey: payload.sessionKey,
3783
+ errName: err instanceof Error ? err.name : typeof err,
3784
+ metric: "chat.event_bus.listener_failed"
3785
+ });
3786
+ }
3758
3787
  }
3759
3788
  onSession(sessionKey, handler) {
3760
3789
  const filtered = (payload) => {
package/dist/plugin2.cjs CHANGED
@@ -3425,13 +3425,13 @@ function buildIntegrationTools(client) {
3425
3425
  return [
3426
3426
  defineTool({
3427
3427
  name: "list_integrations",
3428
- description: "List all integrations installed for this agent, including their status and available config fields.",
3428
+ description: "List all integrations EFFECTIVE for this agent: explicit installs plus connection-/channel-driven activations (e.g. xero, google, myob — active whenever their backing connection is, with no install row) and inherited org/team/project installs. Check `source` and `actualStatus`; driven entries and inherited installs carry no `config` by design — that does NOT mean they are broken or missing.",
3429
3429
  parameters: Type.Object({}, { additionalProperties: false }),
3430
3430
  handler: async () => client.listIntegrations()
3431
3431
  }),
3432
3432
  defineTool({
3433
3433
  name: "get_integration_config",
3434
- description: "Get the current configuration and editable fields for a specific integration.",
3434
+ description: "Get the current configuration and editable fields for a specific integration. `installed: true` with empty config and a driven `source` means the integration is ACTIVE via its connection and simply has no configurable fields. Only `scope: \"agent\"` config is writable via update_integration_config.",
3435
3435
  parameters: Type.Object({ integrationId: Type.String({
3436
3436
  description: "The integration to inspect (e.g. \"voice\", \"slack\")",
3437
3437
  minLength: 1,
package/dist/plugin2.js CHANGED
@@ -3426,13 +3426,13 @@ function buildIntegrationTools(client) {
3426
3426
  return [
3427
3427
  defineTool({
3428
3428
  name: "list_integrations",
3429
- description: "List all integrations installed for this agent, including their status and available config fields.",
3429
+ description: "List all integrations EFFECTIVE for this agent: explicit installs plus connection-/channel-driven activations (e.g. xero, google, myob — active whenever their backing connection is, with no install row) and inherited org/team/project installs. Check `source` and `actualStatus`; driven entries and inherited installs carry no `config` by design — that does NOT mean they are broken or missing.",
3430
3430
  parameters: Type.Object({}, { additionalProperties: false }),
3431
3431
  handler: async () => client.listIntegrations()
3432
3432
  }),
3433
3433
  defineTool({
3434
3434
  name: "get_integration_config",
3435
- description: "Get the current configuration and editable fields for a specific integration.",
3435
+ description: "Get the current configuration and editable fields for a specific integration. `installed: true` with empty config and a driven `source` means the integration is ACTIVE via its connection and simply has no configurable fields. Only `scope: \"agent\"` config is writable via update_integration_config.",
3436
3436
  parameters: Type.Object({ integrationId: Type.String({
3437
3437
  description: "The integration to inspect (e.g. \"voice\", \"slack\")",
3438
3438
  minLength: 1,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfe.ai/openclaw",
3
- "version": "0.4.13",
3
+ "version": "0.4.14",
4
4
  "description": "OpenClaw plugin for Alfe — connects to local gateway daemon via IPC for integration management",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -26,7 +26,7 @@
26
26
  "@auriclabs/logger": "^0.1.1",
27
27
  "@sinclair/typebox": "^0.34.48",
28
28
  "zod": "^4.1.5",
29
- "@alfe.ai/agent-api-client": "^0.17.0",
29
+ "@alfe.ai/agent-api-client": "^0.18.0",
30
30
  "@alfe.ai/config": "^0.4.1"
31
31
  },
32
32
  "peerDependencies": {