@alfe.ai/gateway 0.0.30 → 0.0.32
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/health.js +91 -24
- 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("/
|
|
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(`/
|
|
497
|
+
return this.client.request(`/mobile/numbers/search?${params}`);
|
|
497
498
|
}
|
|
498
499
|
assignMobileNumber(agentId, phoneNumber, countryCode) {
|
|
499
|
-
return this.client.request("/
|
|
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(
|
|
509
|
-
return this.client.request("/
|
|
509
|
+
releaseMobileNumber(agentId) {
|
|
510
|
+
return this.client.request("/mobile/numbers/release", {
|
|
510
511
|
method: "POST",
|
|
511
|
-
body: JSON.stringify({
|
|
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 =
|
|
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
|
-
|
|
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
|
|
4152
|
+
* Set a callback for when the runtime needs restarting — plugins changed or config applied.
|
|
4148
4153
|
*/
|
|
4149
|
-
|
|
4150
|
-
this.
|
|
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.
|
|
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);
|
|
@@ -20019,7 +20024,6 @@ function createLogger(component, additionalData) {
|
|
|
20019
20024
|
const log$1 = createLogger("RuntimeProcess");
|
|
20020
20025
|
const BACKOFF_INITIAL_MS = 1e3;
|
|
20021
20026
|
const BACKOFF_MAX_MS = 3e4;
|
|
20022
|
-
const STABLE_UPTIME_MS = 6e4;
|
|
20023
20027
|
var RuntimeProcess = class {
|
|
20024
20028
|
child = null;
|
|
20025
20029
|
stopped = false;
|
|
@@ -20094,13 +20098,24 @@ var RuntimeProcess = class {
|
|
|
20094
20098
|
}, "Runtime stopped (expected)");
|
|
20095
20099
|
return;
|
|
20096
20100
|
}
|
|
20101
|
+
if (code === 0 && signal == null) {
|
|
20102
|
+
log$1.info({
|
|
20103
|
+
runtime: this.options.runtime,
|
|
20104
|
+
code
|
|
20105
|
+
}, "Runtime exited gracefully — restarting");
|
|
20106
|
+
this.restartTimer = setTimeout(() => {
|
|
20107
|
+
this.restartTimer = null;
|
|
20108
|
+
this.start();
|
|
20109
|
+
}, 500);
|
|
20110
|
+
return;
|
|
20111
|
+
}
|
|
20097
20112
|
log$1.warn({
|
|
20098
20113
|
runtime: this.options.runtime,
|
|
20099
20114
|
code,
|
|
20100
20115
|
signal,
|
|
20101
20116
|
backoffMs: this.backoffMs
|
|
20102
|
-
}, "Runtime
|
|
20103
|
-
if (Date.now() - this.lastStartTime >=
|
|
20117
|
+
}, "Runtime crashed — scheduling restart with backoff");
|
|
20118
|
+
if (Date.now() - this.lastStartTime >= 6e4) this.backoffMs = BACKOFF_INITIAL_MS;
|
|
20104
20119
|
this.restartTimer = setTimeout(() => {
|
|
20105
20120
|
this.restartTimer = null;
|
|
20106
20121
|
this.start();
|
|
@@ -20318,6 +20333,7 @@ var CommandRegistry = class {
|
|
|
20318
20333
|
* 8. Write PID file (non-managed only)
|
|
20319
20334
|
* 9. Handle graceful shutdown
|
|
20320
20335
|
*/
|
|
20336
|
+
const execFileAsync = promisify(execFile);
|
|
20321
20337
|
let config;
|
|
20322
20338
|
let cloudClient;
|
|
20323
20339
|
let ipcServer = null;
|
|
@@ -20495,9 +20511,9 @@ async function startDaemon() {
|
|
|
20495
20511
|
});
|
|
20496
20512
|
const integrationAdapter = new IntegrationManagerAdapter(integrationManager);
|
|
20497
20513
|
cloudClient.setIntegrationManager(integrationAdapter);
|
|
20498
|
-
cloudClient.
|
|
20514
|
+
cloudClient.setRuntimeRestartNeededHandler(() => {
|
|
20499
20515
|
if (runtimeProcess) {
|
|
20500
|
-
logger$1.info("
|
|
20516
|
+
logger$1.info("Runtime state changed — restarting runtime");
|
|
20501
20517
|
runtimeProcess.restart().catch((err) => {
|
|
20502
20518
|
logger$1.error({ err: err instanceof Error ? err.message : String(err) }, "Failed to restart runtime");
|
|
20503
20519
|
});
|
|
@@ -20645,6 +20661,57 @@ async function handleCloudCommand(command) {
|
|
|
20645
20661
|
};
|
|
20646
20662
|
}
|
|
20647
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
|
+
}
|
|
20648
20715
|
if (commandRegistry.has(command.command)) try {
|
|
20649
20716
|
const ctx = buildCommandContext();
|
|
20650
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.
|
|
3
|
+
"version": "0.0.32",
|
|
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.
|
|
26
|
-
"@alfe.ai/config": "^0.0.
|
|
27
|
-
"@alfe.ai/integration-manifest": "^0.0.
|
|
28
|
-
"@alfe.ai/integrations": "^0.0.
|
|
25
|
+
"@alfe.ai/ai-proxy-local": "^0.0.6",
|
|
26
|
+
"@alfe.ai/config": "^0.0.6",
|
|
27
|
+
"@alfe.ai/integration-manifest": "^0.0.9",
|
|
28
|
+
"@alfe.ai/integrations": "^0.0.21"
|
|
29
29
|
},
|
|
30
30
|
"license": "UNLICENSED",
|
|
31
31
|
"scripts": {
|