@alfe.ai/gateway 0.0.17 → 0.0.18
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 +22 -265
- package/package.json +5 -5
package/dist/health.js
CHANGED
|
@@ -12,7 +12,6 @@ import WebSocket from "ws";
|
|
|
12
12
|
import { createConnection, createServer } from "node:net";
|
|
13
13
|
import { execSync, spawn } from "node:child_process";
|
|
14
14
|
import { IntegrationManager, IntegrationManagerAdapter, OpenClawApplier } from "@alfe.ai/integrations";
|
|
15
|
-
import { randomUUID } from "node:crypto";
|
|
16
15
|
import stream, { Readable } from "stream";
|
|
17
16
|
import util, { format } from "util";
|
|
18
17
|
import http from "http";
|
|
@@ -21,6 +20,7 @@ import url from "url";
|
|
|
21
20
|
import http2 from "http2";
|
|
22
21
|
import zlib from "zlib";
|
|
23
22
|
import { EventEmitter } from "events";
|
|
23
|
+
import { randomUUID } from "node:crypto";
|
|
24
24
|
//#region \0rolldown/runtime.js
|
|
25
25
|
var __create = Object.create;
|
|
26
26
|
var __defProp = Object.defineProperty;
|
|
@@ -3465,7 +3465,7 @@ async function loadManagedConfig() {
|
|
|
3465
3465
|
apiKey,
|
|
3466
3466
|
apiEndpoint,
|
|
3467
3467
|
gatewayWsUrl,
|
|
3468
|
-
socketPath:
|
|
3468
|
+
socketPath: SOCKET_PATH,
|
|
3469
3469
|
pidPath: "",
|
|
3470
3470
|
agentId: identity.agentId,
|
|
3471
3471
|
orgId: identity.orgId,
|
|
@@ -3684,22 +3684,6 @@ function createReconciliationReport(results) {
|
|
|
3684
3684
|
};
|
|
3685
3685
|
}
|
|
3686
3686
|
/**
|
|
3687
|
-
* Type guard: is this a cloud SERVICE_RELAY message?
|
|
3688
|
-
*/
|
|
3689
|
-
function isCloudServiceRelay(msg) {
|
|
3690
|
-
return typeof msg === "object" && msg !== null && msg.type === "SERVICE_RELAY";
|
|
3691
|
-
}
|
|
3692
|
-
/**
|
|
3693
|
-
* Create an AGENT_EVENT message for cloud relay.
|
|
3694
|
-
*/
|
|
3695
|
-
function createAgentEvent(agentId, payload) {
|
|
3696
|
-
return {
|
|
3697
|
-
type: "AGENT_EVENT",
|
|
3698
|
-
agentId,
|
|
3699
|
-
payload
|
|
3700
|
-
};
|
|
3701
|
-
}
|
|
3702
|
-
/**
|
|
3703
3687
|
* Type guard: is this a cloud PING message?
|
|
3704
3688
|
*/
|
|
3705
3689
|
function isCloudPing(msg) {
|
|
@@ -3721,7 +3705,7 @@ function isIPCResponse(msg) {
|
|
|
3721
3705
|
const PROTOCOL_VERSION = 1;
|
|
3722
3706
|
//#endregion
|
|
3723
3707
|
//#region src/reconciliation.ts
|
|
3724
|
-
const log$
|
|
3708
|
+
const log$1 = logger$1.child({ component: "Reconciliation" });
|
|
3725
3709
|
var ReconciliationEngine = class {
|
|
3726
3710
|
constructor(manager) {
|
|
3727
3711
|
this.manager = manager;
|
|
@@ -3742,7 +3726,7 @@ var ReconciliationEngine = class {
|
|
|
3742
3726
|
try {
|
|
3743
3727
|
localIntegrations = await this.manager.getInstalledIntegrations();
|
|
3744
3728
|
} catch (err) {
|
|
3745
|
-
log$
|
|
3729
|
+
log$1.error({ err }, "Failed to get local integrations");
|
|
3746
3730
|
localIntegrations = [];
|
|
3747
3731
|
}
|
|
3748
3732
|
const localMap = new Map(localIntegrations.map((i) => [i.id, i]));
|
|
@@ -3756,10 +3740,10 @@ var ReconciliationEngine = class {
|
|
|
3756
3740
|
const id = desired.integrationId;
|
|
3757
3741
|
try {
|
|
3758
3742
|
if (!local) {
|
|
3759
|
-
log$
|
|
3743
|
+
log$1.info(`Installing ${id}@${desired.version}`);
|
|
3760
3744
|
await this.manager.install(id, desired.version, desired.config);
|
|
3761
3745
|
report.installed.push(id);
|
|
3762
|
-
log$
|
|
3746
|
+
log$1.info(`Activating ${id}`);
|
|
3763
3747
|
await this.manager.activate(id);
|
|
3764
3748
|
report.activated.push(id);
|
|
3765
3749
|
report.results.push({
|
|
@@ -3770,14 +3754,14 @@ var ReconciliationEngine = class {
|
|
|
3770
3754
|
return;
|
|
3771
3755
|
}
|
|
3772
3756
|
if (local.version !== desired.version && desired.version !== "" && local.version !== "unknown") {
|
|
3773
|
-
log$
|
|
3757
|
+
log$1.info(`Upgrading ${id}: ${local.version} → ${desired.version}`);
|
|
3774
3758
|
try {
|
|
3775
3759
|
await this.manager.deactivate(id);
|
|
3776
3760
|
await this.manager.uninstall(id);
|
|
3777
3761
|
} catch {}
|
|
3778
3762
|
await this.manager.install(id, desired.version, desired.config);
|
|
3779
3763
|
report.installed.push(id);
|
|
3780
|
-
log$
|
|
3764
|
+
log$1.info(`Activating ${id}`);
|
|
3781
3765
|
await this.manager.activate(id);
|
|
3782
3766
|
report.activated.push(id);
|
|
3783
3767
|
report.results.push({
|
|
@@ -3788,7 +3772,7 @@ var ReconciliationEngine = class {
|
|
|
3788
3772
|
return;
|
|
3789
3773
|
}
|
|
3790
3774
|
if (local.status !== "active") {
|
|
3791
|
-
log$
|
|
3775
|
+
log$1.info(`Activating ${id}`);
|
|
3792
3776
|
await this.manager.activate(id);
|
|
3793
3777
|
report.activated.push(id);
|
|
3794
3778
|
report.results.push({
|
|
@@ -3805,7 +3789,7 @@ var ReconciliationEngine = class {
|
|
|
3805
3789
|
});
|
|
3806
3790
|
} catch (err) {
|
|
3807
3791
|
const message = err instanceof Error ? err.message : String(err);
|
|
3808
|
-
log$
|
|
3792
|
+
log$1.error({ err }, `Error reconciling ${id}`);
|
|
3809
3793
|
report.errors.push({
|
|
3810
3794
|
integrationId: id,
|
|
3811
3795
|
error: message
|
|
@@ -3828,7 +3812,7 @@ var ReconciliationEngine = class {
|
|
|
3828
3812
|
return;
|
|
3829
3813
|
}
|
|
3830
3814
|
try {
|
|
3831
|
-
log$
|
|
3815
|
+
log$1.info(`Removing ${id}`);
|
|
3832
3816
|
if (local.status === "active") {
|
|
3833
3817
|
await this.manager.deactivate(id);
|
|
3834
3818
|
report.deactivated.push(id);
|
|
@@ -3842,7 +3826,7 @@ var ReconciliationEngine = class {
|
|
|
3842
3826
|
});
|
|
3843
3827
|
} catch (err) {
|
|
3844
3828
|
const message = err instanceof Error ? err.message : String(err);
|
|
3845
|
-
log$
|
|
3829
|
+
log$1.error({ err }, `Error removing ${id}`);
|
|
3846
3830
|
report.errors.push({
|
|
3847
3831
|
integrationId: id,
|
|
3848
3832
|
error: message
|
|
@@ -3876,7 +3860,6 @@ var CloudClient = class {
|
|
|
3876
3860
|
config;
|
|
3877
3861
|
onCommand = null;
|
|
3878
3862
|
onConnectionChange = null;
|
|
3879
|
-
onServiceRelay = null;
|
|
3880
3863
|
onPluginsChanged = null;
|
|
3881
3864
|
reconciliationEngine = null;
|
|
3882
3865
|
constructor(config) {
|
|
@@ -3898,20 +3881,6 @@ var CloudClient = class {
|
|
|
3898
3881
|
this.onConnectionChange = handler;
|
|
3899
3882
|
}
|
|
3900
3883
|
/**
|
|
3901
|
-
* Set the handler for incoming SERVICE_RELAY messages (forwarded from services).
|
|
3902
|
-
* Used to bridge service messages to the local agent runtime.
|
|
3903
|
-
*/
|
|
3904
|
-
setServiceRelayHandler(handler) {
|
|
3905
|
-
this.onServiceRelay = handler;
|
|
3906
|
-
}
|
|
3907
|
-
/**
|
|
3908
|
-
* Send an AGENT_EVENT to the cloud gateway for relay to connected services.
|
|
3909
|
-
*/
|
|
3910
|
-
sendAgentEvent(payload) {
|
|
3911
|
-
const msg = createAgentEvent(this.config.agentId, payload);
|
|
3912
|
-
this.send(msg);
|
|
3913
|
-
}
|
|
3914
|
-
/**
|
|
3915
3884
|
* Set the integration manager for reconciliation.
|
|
3916
3885
|
* When set, the cloud client will handle DESIRED_STATE messages automatically.
|
|
3917
3886
|
*/
|
|
@@ -4039,10 +4008,6 @@ var CloudClient = class {
|
|
|
4039
4008
|
await this.handleDesiredState(msg);
|
|
4040
4009
|
return;
|
|
4041
4010
|
}
|
|
4042
|
-
if (isCloudServiceRelay(msg)) {
|
|
4043
|
-
this.handleServiceRelay(msg);
|
|
4044
|
-
return;
|
|
4045
|
-
}
|
|
4046
4011
|
if (isCloudCommand(msg)) {
|
|
4047
4012
|
await this.handleCommand(msg);
|
|
4048
4013
|
return;
|
|
@@ -4123,11 +4088,6 @@ var CloudClient = class {
|
|
|
4123
4088
|
logger$1.error({ err: message }, "Cloud: reconciliation failed");
|
|
4124
4089
|
}
|
|
4125
4090
|
}
|
|
4126
|
-
handleServiceRelay(relay) {
|
|
4127
|
-
logger$1.debug({ sourceServiceId: relay.sourceServiceId }, "Cloud: received SERVICE_RELAY");
|
|
4128
|
-
if (this.onServiceRelay) this.onServiceRelay(relay);
|
|
4129
|
-
else logger$1.warn("Cloud: SERVICE_RELAY received but no handler set — dropping");
|
|
4130
|
-
}
|
|
4131
4091
|
send(msg) {
|
|
4132
4092
|
if (this.ws?.readyState === WebSocket.OPEN) this.ws.send(JSON.stringify(msg));
|
|
4133
4093
|
else logger$1.debug({ readyState: this.ws?.readyState }, "Cloud: send skipped — WebSocket not open");
|
|
@@ -19783,7 +19743,7 @@ function createLogger(component, additionalData) {
|
|
|
19783
19743
|
* Spawns the runtime binary, pipes stdout/stderr to the daemon logger,
|
|
19784
19744
|
* and restarts on crash with exponential backoff.
|
|
19785
19745
|
*/
|
|
19786
|
-
const log
|
|
19746
|
+
const log = createLogger("RuntimeProcess");
|
|
19787
19747
|
const BACKOFF_INITIAL_MS = 1e3;
|
|
19788
19748
|
const BACKOFF_MAX_MS = 3e4;
|
|
19789
19749
|
const STABLE_UPTIME_MS = 6e4;
|
|
@@ -19819,7 +19779,7 @@ var RuntimeProcess = class {
|
|
|
19819
19779
|
if (this.stopped) return;
|
|
19820
19780
|
const { command, args } = this.resolveCommand();
|
|
19821
19781
|
this.lastStartTime = Date.now();
|
|
19822
|
-
log
|
|
19782
|
+
log.info({
|
|
19823
19783
|
runtime: this.options.runtime,
|
|
19824
19784
|
command,
|
|
19825
19785
|
args,
|
|
@@ -19838,14 +19798,14 @@ var RuntimeProcess = class {
|
|
|
19838
19798
|
});
|
|
19839
19799
|
this.child.stdout?.on("data", (data) => {
|
|
19840
19800
|
const lines = data.toString().trim().split("\n");
|
|
19841
|
-
for (const line of lines) log
|
|
19801
|
+
for (const line of lines) log.info({
|
|
19842
19802
|
runtime: this.options.runtime,
|
|
19843
19803
|
stream: "stdout"
|
|
19844
19804
|
}, line);
|
|
19845
19805
|
});
|
|
19846
19806
|
this.child.stderr?.on("data", (data) => {
|
|
19847
19807
|
const lines = data.toString().trim().split("\n");
|
|
19848
|
-
for (const line of lines) log
|
|
19808
|
+
for (const line of lines) log.warn({
|
|
19849
19809
|
runtime: this.options.runtime,
|
|
19850
19810
|
stream: "stderr"
|
|
19851
19811
|
}, line);
|
|
@@ -19853,14 +19813,14 @@ var RuntimeProcess = class {
|
|
|
19853
19813
|
this.child.on("exit", (code, signal) => {
|
|
19854
19814
|
this.child = null;
|
|
19855
19815
|
if (this.stopped) {
|
|
19856
|
-
log
|
|
19816
|
+
log.info({
|
|
19857
19817
|
runtime: this.options.runtime,
|
|
19858
19818
|
code,
|
|
19859
19819
|
signal
|
|
19860
19820
|
}, "Runtime stopped (expected)");
|
|
19861
19821
|
return;
|
|
19862
19822
|
}
|
|
19863
|
-
log
|
|
19823
|
+
log.warn({
|
|
19864
19824
|
runtime: this.options.runtime,
|
|
19865
19825
|
code,
|
|
19866
19826
|
signal,
|
|
@@ -19874,7 +19834,7 @@ var RuntimeProcess = class {
|
|
|
19874
19834
|
this.backoffMs = Math.min(this.backoffMs * 2, BACKOFF_MAX_MS);
|
|
19875
19835
|
});
|
|
19876
19836
|
this.child.on("error", (err) => {
|
|
19877
|
-
log
|
|
19837
|
+
log.error({
|
|
19878
19838
|
runtime: this.options.runtime,
|
|
19879
19839
|
err: err.message
|
|
19880
19840
|
}, "Runtime process error");
|
|
@@ -19893,7 +19853,7 @@ var RuntimeProcess = class {
|
|
|
19893
19853
|
if (!child) return;
|
|
19894
19854
|
return new Promise((resolve) => {
|
|
19895
19855
|
const killTimer = setTimeout(() => {
|
|
19896
|
-
log
|
|
19856
|
+
log.warn({ runtime: this.options.runtime }, "Runtime did not exit in time — sending SIGKILL");
|
|
19897
19857
|
child.kill("SIGKILL");
|
|
19898
19858
|
}, 5e3);
|
|
19899
19859
|
child.on("exit", () => {
|
|
@@ -19907,7 +19867,7 @@ var RuntimeProcess = class {
|
|
|
19907
19867
|
* Restart the runtime process (stop then start with fresh backoff).
|
|
19908
19868
|
*/
|
|
19909
19869
|
async restart() {
|
|
19910
|
-
log
|
|
19870
|
+
log.info({ runtime: this.options.runtime }, "Restarting runtime...");
|
|
19911
19871
|
await this.stop();
|
|
19912
19872
|
this.stopped = false;
|
|
19913
19873
|
this.backoffMs = BACKOFF_INITIAL_MS;
|
|
@@ -19921,175 +19881,6 @@ var RuntimeProcess = class {
|
|
|
19921
19881
|
}
|
|
19922
19882
|
};
|
|
19923
19883
|
//#endregion
|
|
19924
|
-
//#region src/local-agent-relay.ts
|
|
19925
|
-
/**
|
|
19926
|
-
* LocalAgentRelay — bridges the cloud gateway to the agent runtime's local
|
|
19927
|
-
* WebSocket server (e.g. OpenClaw on localhost:18789).
|
|
19928
|
-
*
|
|
19929
|
-
* Incoming SERVICE_RELAY messages from the cloud are forwarded to the local WS.
|
|
19930
|
-
* Events and responses from the local WS are forwarded as AGENT_EVENT to the cloud.
|
|
19931
|
-
*/
|
|
19932
|
-
const log = createLogger("LocalAgentRelay");
|
|
19933
|
-
const CONNECT_RETRY_DELAYS = [
|
|
19934
|
-
500,
|
|
19935
|
-
1e3,
|
|
19936
|
-
2e3,
|
|
19937
|
-
4e3,
|
|
19938
|
-
8e3,
|
|
19939
|
-
15e3,
|
|
19940
|
-
3e4
|
|
19941
|
-
];
|
|
19942
|
-
var LocalAgentRelay = class {
|
|
19943
|
-
ws = null;
|
|
19944
|
-
stopped = false;
|
|
19945
|
-
connected = false;
|
|
19946
|
-
retryCount = 0;
|
|
19947
|
-
retryTimer = null;
|
|
19948
|
-
constructor(options) {
|
|
19949
|
-
this.options = options;
|
|
19950
|
-
}
|
|
19951
|
-
/**
|
|
19952
|
-
* Start connecting to the local runtime WS.
|
|
19953
|
-
*/
|
|
19954
|
-
start() {
|
|
19955
|
-
log.debug({ wsUrl: this.options.wsUrl }, "Local relay starting...");
|
|
19956
|
-
this.stopped = false;
|
|
19957
|
-
this.doConnect();
|
|
19958
|
-
}
|
|
19959
|
-
/**
|
|
19960
|
-
* Stop the relay and close the local WS connection.
|
|
19961
|
-
*/
|
|
19962
|
-
stop() {
|
|
19963
|
-
log.debug("Local relay stopping...");
|
|
19964
|
-
this.stopped = true;
|
|
19965
|
-
if (this.retryTimer) {
|
|
19966
|
-
clearTimeout(this.retryTimer);
|
|
19967
|
-
this.retryTimer = null;
|
|
19968
|
-
}
|
|
19969
|
-
if (this.ws) {
|
|
19970
|
-
log.debug({ readyState: this.ws.readyState }, "Local relay: closing WebSocket");
|
|
19971
|
-
try {
|
|
19972
|
-
this.ws.close(1e3);
|
|
19973
|
-
} catch (err) {
|
|
19974
|
-
log.debug({ err }, "websocket close failed during relay stop");
|
|
19975
|
-
}
|
|
19976
|
-
this.ws = null;
|
|
19977
|
-
}
|
|
19978
|
-
this.connected = false;
|
|
19979
|
-
log.debug("Local relay stopped");
|
|
19980
|
-
}
|
|
19981
|
-
/**
|
|
19982
|
-
* Forward a message payload from the cloud to the local runtime WS.
|
|
19983
|
-
*/
|
|
19984
|
-
forward(payload) {
|
|
19985
|
-
if (this.ws?.readyState !== WebSocket.OPEN) {
|
|
19986
|
-
log.warn({ readyState: this.ws?.readyState }, "Cannot forward to local runtime — not connected");
|
|
19987
|
-
return;
|
|
19988
|
-
}
|
|
19989
|
-
const data = typeof payload === "string" ? payload : JSON.stringify(payload);
|
|
19990
|
-
log.debug({ size: data.length }, "Local relay: forwarding message to runtime");
|
|
19991
|
-
this.ws.send(data);
|
|
19992
|
-
}
|
|
19993
|
-
get isConnected() {
|
|
19994
|
-
return this.connected;
|
|
19995
|
-
}
|
|
19996
|
-
doConnect() {
|
|
19997
|
-
if (this.stopped) {
|
|
19998
|
-
log.debug("Local relay: doConnect skipped — relay is stopped");
|
|
19999
|
-
return;
|
|
20000
|
-
}
|
|
20001
|
-
log.info({
|
|
20002
|
-
url: this.options.wsUrl,
|
|
20003
|
-
retryCount: this.retryCount
|
|
20004
|
-
}, "Connecting to local runtime WS...");
|
|
20005
|
-
this.ws = new WebSocket(this.options.wsUrl, { handshakeTimeout: 1e4 });
|
|
20006
|
-
this.ws.on("open", () => {
|
|
20007
|
-
log.info("Local runtime WS connected — performing handshake");
|
|
20008
|
-
this.retryCount = 0;
|
|
20009
|
-
this.performHandshake();
|
|
20010
|
-
});
|
|
20011
|
-
this.ws.on("message", (data) => {
|
|
20012
|
-
const text = Buffer.isBuffer(data) ? data.toString("utf-8") : Buffer.from(data).toString("utf-8");
|
|
20013
|
-
log.debug({ size: text.length }, "Local relay: received message");
|
|
20014
|
-
this.handleLocalMessage(text);
|
|
20015
|
-
});
|
|
20016
|
-
this.ws.on("close", (code, reason) => {
|
|
20017
|
-
log.warn({
|
|
20018
|
-
code,
|
|
20019
|
-
reason: reason.toString()
|
|
20020
|
-
}, "Local runtime WS disconnected");
|
|
20021
|
-
this.connected = false;
|
|
20022
|
-
this.scheduleReconnect();
|
|
20023
|
-
});
|
|
20024
|
-
this.ws.on("error", (err) => {
|
|
20025
|
-
log.warn({
|
|
20026
|
-
err: err.message,
|
|
20027
|
-
url: this.options.wsUrl
|
|
20028
|
-
}, "Local runtime WS error");
|
|
20029
|
-
});
|
|
20030
|
-
}
|
|
20031
|
-
performHandshake() {
|
|
20032
|
-
log.debug("Local relay: sending connect handshake");
|
|
20033
|
-
const connectReq = {
|
|
20034
|
-
type: "req",
|
|
20035
|
-
id: randomUUID(),
|
|
20036
|
-
method: "connect",
|
|
20037
|
-
params: {
|
|
20038
|
-
minProtocol: 3,
|
|
20039
|
-
maxProtocol: 3,
|
|
20040
|
-
client: {
|
|
20041
|
-
id: "gateway-client",
|
|
20042
|
-
displayName: "Alfe Daemon Relay",
|
|
20043
|
-
version: "0.1.0",
|
|
20044
|
-
platform: process.platform,
|
|
20045
|
-
mode: "backend",
|
|
20046
|
-
instanceId: randomUUID()
|
|
20047
|
-
},
|
|
20048
|
-
caps: [],
|
|
20049
|
-
role: "operator",
|
|
20050
|
-
scopes: ["operator.admin"],
|
|
20051
|
-
auth: { token: this.options.apiKey }
|
|
20052
|
-
}
|
|
20053
|
-
};
|
|
20054
|
-
this.ws?.send(JSON.stringify(connectReq));
|
|
20055
|
-
this.handshakeId = connectReq.id;
|
|
20056
|
-
}
|
|
20057
|
-
handshakeId = null;
|
|
20058
|
-
handleLocalMessage(raw) {
|
|
20059
|
-
let msg;
|
|
20060
|
-
try {
|
|
20061
|
-
msg = JSON.parse(raw);
|
|
20062
|
-
} catch {
|
|
20063
|
-
return;
|
|
20064
|
-
}
|
|
20065
|
-
if (this.handshakeId && msg.id === this.handshakeId) {
|
|
20066
|
-
this.handshakeId = null;
|
|
20067
|
-
if (msg.ok) {
|
|
20068
|
-
this.connected = true;
|
|
20069
|
-
log.info("Local runtime handshake complete — relay active");
|
|
20070
|
-
} else {
|
|
20071
|
-
log.error({ error: msg.error }, "Local runtime handshake failed");
|
|
20072
|
-
this.ws?.close(1008, "Handshake failed");
|
|
20073
|
-
}
|
|
20074
|
-
return;
|
|
20075
|
-
}
|
|
20076
|
-
this.options.onAgentMessage(msg);
|
|
20077
|
-
}
|
|
20078
|
-
scheduleReconnect() {
|
|
20079
|
-
if (this.stopped) return;
|
|
20080
|
-
const delay = CONNECT_RETRY_DELAYS[Math.min(this.retryCount, CONNECT_RETRY_DELAYS.length - 1)];
|
|
20081
|
-
this.retryCount++;
|
|
20082
|
-
log.info({
|
|
20083
|
-
delayMs: delay,
|
|
20084
|
-
retryCount: this.retryCount
|
|
20085
|
-
}, "Scheduling reconnect to local runtime");
|
|
20086
|
-
this.retryTimer = setTimeout(() => {
|
|
20087
|
-
this.retryTimer = null;
|
|
20088
|
-
this.doConnect();
|
|
20089
|
-
}, delay);
|
|
20090
|
-
}
|
|
20091
|
-
};
|
|
20092
|
-
//#endregion
|
|
20093
19884
|
//#region src/daemon.ts
|
|
20094
19885
|
/**
|
|
20095
19886
|
* Alfe Gateway Daemon — main entry point.
|
|
@@ -20113,7 +19904,6 @@ let startedAt;
|
|
|
20113
19904
|
let integrationManager;
|
|
20114
19905
|
let aiProxyServer = null;
|
|
20115
19906
|
let runtimeProcess = null;
|
|
20116
|
-
let localRelay = null;
|
|
20117
19907
|
let aiProxyUrl = null;
|
|
20118
19908
|
let aiProxyRunning = false;
|
|
20119
19909
|
let cloudConnected = false;
|
|
@@ -20295,7 +20085,6 @@ async function startDaemon() {
|
|
|
20295
20085
|
logger$1.debug({ runtime: config.runtime }, "Starting agent runtime...");
|
|
20296
20086
|
const runtimeCfg = config.runtimes[config.runtime];
|
|
20297
20087
|
if (runtimeCfg) {
|
|
20298
|
-
const runtimeToken = randomUUID();
|
|
20299
20088
|
logger$1.debug({
|
|
20300
20089
|
runtime: config.runtime,
|
|
20301
20090
|
workspace: runtimeCfg.workspace
|
|
@@ -20303,37 +20092,10 @@ async function startDaemon() {
|
|
|
20303
20092
|
runtimeProcess = new RuntimeProcess({
|
|
20304
20093
|
runtime: config.runtime,
|
|
20305
20094
|
workspace: runtimeCfg.workspace,
|
|
20306
|
-
env: {
|
|
20307
|
-
ALFE_GATEWAY_SOCKET: config.socketPath,
|
|
20308
|
-
ALFE_API_KEY: config.apiKey,
|
|
20309
|
-
ALFE_API_URL: config.apiEndpoint,
|
|
20310
|
-
ALFE_AGENT_ID: config.agentId,
|
|
20311
|
-
ANTHROPIC_BASE_URL: aiProxyUrl ?? "http://127.0.0.1:18193",
|
|
20312
|
-
OPENAI_BASE_URL: aiProxyUrl ?? "http://127.0.0.1:18193",
|
|
20313
|
-
ANTHROPIC_API_KEY: config.apiKey,
|
|
20314
|
-
OPENAI_API_KEY: config.apiKey,
|
|
20315
|
-
OPENCLAW_GATEWAY_TOKEN: runtimeToken
|
|
20316
|
-
}
|
|
20095
|
+
env: {}
|
|
20317
20096
|
});
|
|
20318
20097
|
runtimeProcess.start();
|
|
20319
20098
|
logger$1.debug("Runtime process started");
|
|
20320
|
-
const RUNTIME_WS_PORT = 18789;
|
|
20321
|
-
logger$1.debug({ runtimeWsPort: RUNTIME_WS_PORT }, "Creating local agent relay...");
|
|
20322
|
-
const relay = new LocalAgentRelay({
|
|
20323
|
-
wsUrl: `ws://127.0.0.1:${String(RUNTIME_WS_PORT)}`,
|
|
20324
|
-
apiKey: runtimeToken,
|
|
20325
|
-
onAgentMessage: (payload) => {
|
|
20326
|
-
cloudClient.sendAgentEvent(payload);
|
|
20327
|
-
}
|
|
20328
|
-
});
|
|
20329
|
-
localRelay = relay;
|
|
20330
|
-
cloudClient.setServiceRelayHandler((msg) => {
|
|
20331
|
-
relay.forward(msg.payload);
|
|
20332
|
-
});
|
|
20333
|
-
logger$1.debug("Scheduling local relay start in 2s (waiting for runtime WS server)...");
|
|
20334
|
-
setTimeout(() => {
|
|
20335
|
-
relay.start();
|
|
20336
|
-
}, 2e3);
|
|
20337
20099
|
} else logger$1.warn({ runtime: config.runtime }, "No runtime config found — skipping runtime start");
|
|
20338
20100
|
}
|
|
20339
20101
|
if (!managed) await writePidFile();
|
|
@@ -20341,11 +20103,6 @@ async function startDaemon() {
|
|
|
20341
20103
|
if (shuttingDown) return;
|
|
20342
20104
|
shuttingDown = true;
|
|
20343
20105
|
logger$1.info({ signal }, "Shutting down...");
|
|
20344
|
-
if (localRelay) {
|
|
20345
|
-
logger$1.debug("Stopping local relay...");
|
|
20346
|
-
localRelay.stop();
|
|
20347
|
-
logger$1.debug("Local relay stopped");
|
|
20348
|
-
}
|
|
20349
20106
|
if (runtimeProcess) {
|
|
20350
20107
|
logger$1.debug("Stopping runtime process...");
|
|
20351
20108
|
await runtimeProcess.stop();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alfe.ai/gateway",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.18",
|
|
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/
|
|
27
|
-
"@alfe.ai/
|
|
28
|
-
"@alfe.ai/
|
|
25
|
+
"@alfe.ai/ai-proxy-local": "^0.0.5",
|
|
26
|
+
"@alfe.ai/config": "^0.0.5",
|
|
27
|
+
"@alfe.ai/doctor": "^0.0.6",
|
|
28
|
+
"@alfe.ai/integrations": "^0.0.10"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/ws": "^8.5.13",
|