@alfe.ai/gateway 0.0.31 → 0.0.33

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/health.js +78 -21
  2. package/package.json +5 -5
package/dist/health.js CHANGED
@@ -1,6 +1,8 @@
1
1
  import { n as logger$1 } from "./logger.js";
2
2
  import { createRequire } from "node:module";
3
3
  import { mkdir, readFile, unlink, writeFile } from "node:fs/promises";
4
+ import { execFile, execSync, spawn } from "node:child_process";
5
+ import { promisify } from "node:util";
4
6
  import { join } from "node:path";
5
7
  import { homedir } from "node:os";
6
8
  import pino from "pino";
@@ -10,7 +12,6 @@ import crypto from "crypto";
10
12
  import { parse } from "smol-toml";
11
13
  import WebSocket from "ws";
12
14
  import { createConnection, createServer } from "node:net";
13
- import { execSync, spawn } from "node:child_process";
14
15
  import { IntegrationManager, IntegrationManagerAdapter, OpenClawApplier } from "@alfe.ai/integrations";
15
16
  import stream, { Readable } from "stream";
16
17
  import util, { format } from "util";
@@ -487,16 +488,16 @@ var IntegrationsService = class {
487
488
  return this.client.request(`/discord/guilds/${encodeURIComponent(guildId)}/channels`);
488
489
  }
489
490
  listMobileNumbers() {
490
- return this.client.request("/twilio/numbers");
491
+ return this.client.request("/mobile/numbers");
491
492
  }
492
493
  searchMobileNumbers(country, query) {
493
494
  const params = new URLSearchParams();
494
495
  if (country) params.set("country", country);
495
496
  if (query) params.set("query", query);
496
- return this.client.request(`/twilio/numbers/search?${params}`);
497
+ return this.client.request(`/mobile/numbers/search?${params}`);
497
498
  }
498
499
  assignMobileNumber(agentId, phoneNumber, countryCode) {
499
- return this.client.request("/twilio/numbers/assign", {
500
+ return this.client.request("/mobile/numbers/assign", {
500
501
  method: "POST",
501
502
  body: JSON.stringify({
502
503
  agentId,
@@ -505,12 +506,15 @@ var IntegrationsService = class {
505
506
  })
506
507
  });
507
508
  }
508
- releaseMobileNumber(phoneSid) {
509
- return this.client.request("/twilio/numbers/release", {
509
+ releaseMobileNumber(agentId) {
510
+ return this.client.request("/mobile/numbers/release", {
510
511
  method: "POST",
511
- body: JSON.stringify({ phoneSid })
512
+ body: JSON.stringify({ agentId })
512
513
  });
513
514
  }
515
+ getMobileNumber(agentId) {
516
+ return this.client.request(`/mobile/numbers?agentId=${encodeURIComponent(agentId)}`);
517
+ }
514
518
  recallJoinMeeting(agentId, meetingUrl, botName) {
515
519
  if (this.voiceClient) return this.voiceClient.request("/api/join", {
516
520
  method: "POST",
@@ -3704,7 +3708,7 @@ async function loadDaemonConfig() {
3704
3708
  if (isManagedMode()) return loadManagedConfig();
3705
3709
  let alfeConfig;
3706
3710
  try {
3707
- alfeConfig = await readConfig();
3711
+ alfeConfig = readConfig();
3708
3712
  } catch {
3709
3713
  throw new Error("Alfe not configured. Run `alfe login` first.");
3710
3714
  }
@@ -3946,7 +3950,8 @@ var ReconciliationEngine = class {
3946
3950
  activated: [],
3947
3951
  deactivated: [],
3948
3952
  uninstalled: [],
3949
- errors: []
3953
+ errors: [],
3954
+ configApplied: false
3950
3955
  };
3951
3956
  let localIntegrations;
3952
3957
  try {
@@ -3970,7 +3975,7 @@ var ReconciliationEngine = class {
3970
3975
  await this.manager.install(id, desired.version, desired.config);
3971
3976
  report.installed.push(id);
3972
3977
  log$2.info(`Activating ${id}`);
3973
- await this.manager.activate(id);
3978
+ if ((await this.manager.activate(id)).configApplied) report.configApplied = true;
3974
3979
  report.activated.push(id);
3975
3980
  report.results.push({
3976
3981
  integrationId: id,
@@ -3981,7 +3986,7 @@ var ReconciliationEngine = class {
3981
3986
  }
3982
3987
  if (local.version !== desired.version && desired.version !== "" && local.version !== "unknown") {
3983
3988
  log$2.info(`Upgrading ${id}: ${local.version} → ${desired.version}`);
3984
- await this.manager.reinstall(id, desired.version, desired.config);
3989
+ if ((await this.manager.reinstall(id, desired.version, desired.config)).configApplied) report.configApplied = true;
3985
3990
  report.installed.push(id);
3986
3991
  report.activated.push(id);
3987
3992
  report.results.push({
@@ -3994,7 +3999,7 @@ var ReconciliationEngine = class {
3994
3999
  if (local.status === "error") {
3995
4000
  if (desired.reinstallRequestedAt && local.installedAt && desired.reinstallRequestedAt > local.installedAt) {
3996
4001
  log$2.info(`Reinstalling ${id} from error state (requested: ${desired.reinstallRequestedAt}, installed: ${local.installedAt})`);
3997
- await this.manager.reinstall(id, desired.version, desired.config);
4002
+ if ((await this.manager.reinstall(id, desired.version, desired.config)).configApplied) report.configApplied = true;
3998
4003
  report.installed.push(id);
3999
4004
  report.activated.push(id);
4000
4005
  report.results.push({
@@ -4019,7 +4024,7 @@ var ReconciliationEngine = class {
4019
4024
  }
4020
4025
  if (local.status !== "active") {
4021
4026
  log$2.info(`Activating ${id}`);
4022
- await this.manager.activate(id);
4027
+ if ((await this.manager.activate(id)).configApplied) report.configApplied = true;
4023
4028
  report.activated.push(id);
4024
4029
  report.results.push({
4025
4030
  integrationId: id,
@@ -4030,7 +4035,7 @@ var ReconciliationEngine = class {
4030
4035
  }
4031
4036
  if (desired.reinstallRequestedAt && local.installedAt && desired.reinstallRequestedAt > local.installedAt) {
4032
4037
  log$2.info(`Reinstall requested for ${id} (requested: ${desired.reinstallRequestedAt}, installed: ${local.installedAt})`);
4033
- await this.manager.reinstall(id, desired.version, desired.config);
4038
+ if ((await this.manager.reinstall(id, desired.version, desired.config)).configApplied) report.configApplied = true;
4034
4039
  report.installed.push(id);
4035
4040
  report.activated.push(id);
4036
4041
  report.results.push({
@@ -4118,7 +4123,7 @@ var CloudClient = class {
4118
4123
  config;
4119
4124
  onCommand = null;
4120
4125
  onConnectionChange = null;
4121
- onPluginsChanged = null;
4126
+ onRuntimeRestartNeeded = null;
4122
4127
  onReconciliationComplete = null;
4123
4128
  reconciliationEngine = null;
4124
4129
  constructor(config) {
@@ -4144,10 +4149,10 @@ var CloudClient = class {
4144
4149
  * When set, the cloud client will handle DESIRED_STATE messages automatically.
4145
4150
  */
4146
4151
  /**
4147
- * Set a callback for when plugins change (install/uninstall)used to restart the runtime.
4152
+ * Set a callback for when the runtime needs restarting plugins changed or config applied.
4148
4153
  */
4149
- setPluginsChangedHandler(handler) {
4150
- this.onPluginsChanged = handler;
4154
+ setRuntimeRestartNeededHandler(handler) {
4155
+ this.onRuntimeRestartNeeded = handler;
4151
4156
  }
4152
4157
  /**
4153
4158
  * Set a callback for when reconciliation completes — used to rebuild command registry.
@@ -4354,7 +4359,7 @@ var CloudClient = class {
4354
4359
  }, "Cloud: reconciliation complete");
4355
4360
  const reportMsg = createReconciliationReport(report.results);
4356
4361
  this.send(reportMsg);
4357
- if ((report.installed.length > 0 || report.uninstalled.length > 0) && this.onPluginsChanged) this.onPluginsChanged();
4362
+ if ((report.installed.length > 0 || report.uninstalled.length > 0 || report.configApplied) && this.onRuntimeRestartNeeded) this.onRuntimeRestartNeeded();
4358
4363
  this.onReconciliationComplete?.();
4359
4364
  } catch (err) {
4360
4365
  const message = err instanceof Error ? err.message : String(err);
@@ -20328,6 +20333,7 @@ var CommandRegistry = class {
20328
20333
  * 8. Write PID file (non-managed only)
20329
20334
  * 9. Handle graceful shutdown
20330
20335
  */
20336
+ const execFileAsync = promisify(execFile);
20331
20337
  let config;
20332
20338
  let cloudClient;
20333
20339
  let ipcServer = null;
@@ -20505,9 +20511,9 @@ async function startDaemon() {
20505
20511
  });
20506
20512
  const integrationAdapter = new IntegrationManagerAdapter(integrationManager);
20507
20513
  cloudClient.setIntegrationManager(integrationAdapter);
20508
- cloudClient.setPluginsChangedHandler(() => {
20514
+ cloudClient.setRuntimeRestartNeededHandler(() => {
20509
20515
  if (runtimeProcess) {
20510
- logger$1.info("Plugins changed — restarting runtime to load new plugins");
20516
+ logger$1.info("Runtime state changed — restarting runtime");
20511
20517
  runtimeProcess.restart().catch((err) => {
20512
20518
  logger$1.error({ err: err instanceof Error ? err.message : String(err) }, "Failed to restart runtime");
20513
20519
  });
@@ -20655,6 +20661,57 @@ async function handleCloudCommand(command) {
20655
20661
  };
20656
20662
  }
20657
20663
  }
20664
+ if (command.command === "alfe.config_set") {
20665
+ const payload = command.payload;
20666
+ const key = payload?.key;
20667
+ const value = payload?.value;
20668
+ if (!key || value === void 0) return {
20669
+ type: "COMMAND_ACK",
20670
+ commandId: command.commandId,
20671
+ status: "error",
20672
+ result: {
20673
+ code: "INVALID_PAYLOAD",
20674
+ message: "alfe.config_set requires key and value"
20675
+ }
20676
+ };
20677
+ try {
20678
+ await execFileAsync("openclaw", [
20679
+ "config",
20680
+ "set",
20681
+ key,
20682
+ value
20683
+ ], { timeout: 1e4 });
20684
+ logger$1.info({
20685
+ key,
20686
+ value
20687
+ }, "Applied config via openclaw config set");
20688
+ return {
20689
+ type: "COMMAND_ACK",
20690
+ commandId: command.commandId,
20691
+ status: "ok",
20692
+ result: {
20693
+ key,
20694
+ value
20695
+ }
20696
+ };
20697
+ } catch (err) {
20698
+ const message = err instanceof Error ? err.message : String(err);
20699
+ logger$1.error({
20700
+ err: message,
20701
+ key,
20702
+ value
20703
+ }, "Failed to apply config via openclaw");
20704
+ return {
20705
+ type: "COMMAND_ACK",
20706
+ commandId: command.commandId,
20707
+ status: "error",
20708
+ result: {
20709
+ code: "CONFIG_SET_FAILED",
20710
+ message
20711
+ }
20712
+ };
20713
+ }
20714
+ }
20658
20715
  if (commandRegistry.has(command.command)) try {
20659
20716
  const ctx = buildCommandContext();
20660
20717
  const result = await commandRegistry.execute(command.command, typeof command.payload === "object" && command.payload !== null ? command.payload : {}, ctx);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfe.ai/gateway",
3
- "version": "0.0.31",
3
+ "version": "0.0.33",
4
4
  "description": "Alfe local gateway daemon — persistent control plane for agent integrations",
5
5
  "type": "module",
6
6
  "bin": {
@@ -22,10 +22,10 @@
22
22
  "pino-roll": "^1.2.0",
23
23
  "smol-toml": ">=1.6.1",
24
24
  "ws": "^8.18.0",
25
- "@alfe.ai/ai-proxy-local": "^0.0.6",
26
- "@alfe.ai/config": "^0.0.6",
27
- "@alfe.ai/integration-manifest": "^0.0.8",
28
- "@alfe.ai/integrations": "^0.0.20"
25
+ "@alfe.ai/ai-proxy-local": "^0.0.7",
26
+ "@alfe.ai/config": "^0.0.7",
27
+ "@alfe.ai/integration-manifest": "^0.0.9",
28
+ "@alfe.ai/integrations": "^0.0.21"
29
29
  },
30
30
  "license": "UNLICENSED",
31
31
  "scripts": {