@alfe.ai/gateway 0.10.3 → 0.10.5
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 +45 -4
- package/package.json +2 -2
package/dist/health.js
CHANGED
|
@@ -6115,7 +6115,7 @@ var ReconciliationEngine = class {
|
|
|
6115
6115
|
log$4.info(`Reinstalling ${id} on version change (reinstall requested: ${desired.reinstallRequestedAt}, installed: ${local.installedAt}): ${local.version} → ${desired.version}`);
|
|
6116
6116
|
this.manager.resetReinstallAttempts(id);
|
|
6117
6117
|
this.activateAttempts.delete(id);
|
|
6118
|
-
if ((await this.manager.reinstall(id, desired.version, desired.config, desired.customSource)).configApplied) report.configApplied = true;
|
|
6118
|
+
if ((await this.manager.reinstall(id, desired.version, desired.config, desired.customSource, { reinstallRequestedAt: desired.reinstallRequestedAt })).configApplied) report.configApplied = true;
|
|
6119
6119
|
report.installed.push(id);
|
|
6120
6120
|
report.activated.push(id);
|
|
6121
6121
|
report.results.push({
|
|
@@ -6160,7 +6160,7 @@ var ReconciliationEngine = class {
|
|
|
6160
6160
|
log$4.info(`Reinstalling ${id} from error state (requested: ${desired.reinstallRequestedAt}, installed: ${local.installedAt})`);
|
|
6161
6161
|
this.manager.resetReinstallAttempts(id);
|
|
6162
6162
|
this.activateAttempts.delete(id);
|
|
6163
|
-
if ((await this.manager.reinstall(id, desired.version, desired.config, desired.customSource)).configApplied) report.configApplied = true;
|
|
6163
|
+
if ((await this.manager.reinstall(id, desired.version, desired.config, desired.customSource, { reinstallRequestedAt: desired.reinstallRequestedAt })).configApplied) report.configApplied = true;
|
|
6164
6164
|
report.installed.push(id);
|
|
6165
6165
|
report.activated.push(id);
|
|
6166
6166
|
report.results.push({
|
|
@@ -6270,7 +6270,7 @@ var ReconciliationEngine = class {
|
|
|
6270
6270
|
log$4.info(`Reinstalling ${id} from stale installing state (requested: ${desired.reinstallRequestedAt}, installed: ${local.installedAt})`);
|
|
6271
6271
|
this.manager.resetReinstallAttempts(id);
|
|
6272
6272
|
this.activateAttempts.delete(id);
|
|
6273
|
-
if ((await this.manager.reinstall(id, desired.version, desired.config, desired.customSource)).configApplied) report.configApplied = true;
|
|
6273
|
+
if ((await this.manager.reinstall(id, desired.version, desired.config, desired.customSource, { reinstallRequestedAt: desired.reinstallRequestedAt })).configApplied) report.configApplied = true;
|
|
6274
6274
|
report.installed.push(id);
|
|
6275
6275
|
report.activated.push(id);
|
|
6276
6276
|
report.results.push({
|
|
@@ -6345,7 +6345,7 @@ var ReconciliationEngine = class {
|
|
|
6345
6345
|
log$4.info(`Reinstall requested for ${id} (requested: ${desired.reinstallRequestedAt}, installed: ${local.installedAt})`);
|
|
6346
6346
|
this.manager.resetReinstallAttempts(id);
|
|
6347
6347
|
this.activateAttempts.delete(id);
|
|
6348
|
-
if ((await this.manager.reinstall(id, desired.version, desired.config, desired.customSource)).configApplied) report.configApplied = true;
|
|
6348
|
+
if ((await this.manager.reinstall(id, desired.version, desired.config, desired.customSource, { reinstallRequestedAt: desired.reinstallRequestedAt })).configApplied) report.configApplied = true;
|
|
6349
6349
|
report.installed.push(id);
|
|
6350
6350
|
report.activated.push(id);
|
|
6351
6351
|
report.results.push({
|
|
@@ -7633,9 +7633,13 @@ async function stopExistingDaemon() {
|
|
|
7633
7633
|
* Each connected plugin registers with its name/version and receives
|
|
7634
7634
|
* commands from the daemon (forwarded from cloud).
|
|
7635
7635
|
*/
|
|
7636
|
+
/** Same-PID re-registrations inside this window before the flap warning fires. */
|
|
7637
|
+
const SAME_PID_FLAP_WINDOW_MS = 6e4;
|
|
7636
7638
|
var IPCServer = class {
|
|
7637
7639
|
server = null;
|
|
7638
7640
|
connections = /* @__PURE__ */ new Map();
|
|
7641
|
+
samePidReplacements = /* @__PURE__ */ new Map();
|
|
7642
|
+
samePidFlapWarnedAt = /* @__PURE__ */ new Map();
|
|
7639
7643
|
socketPath;
|
|
7640
7644
|
requestHandler = null;
|
|
7641
7645
|
constructor(socketPath, daemonVersion = "unknown") {
|
|
@@ -7696,6 +7700,8 @@ var IPCServer = class {
|
|
|
7696
7700
|
});
|
|
7697
7701
|
for (const conn of this.connections.values()) conn.socket.destroy();
|
|
7698
7702
|
this.connections.clear();
|
|
7703
|
+
this.samePidReplacements.clear();
|
|
7704
|
+
this.samePidFlapWarnedAt.clear();
|
|
7699
7705
|
});
|
|
7700
7706
|
}
|
|
7701
7707
|
/**
|
|
@@ -7871,6 +7877,40 @@ var IPCServer = class {
|
|
|
7871
7877
|
}, "IPC: unhandled message");
|
|
7872
7878
|
}
|
|
7873
7879
|
}
|
|
7880
|
+
/**
|
|
7881
|
+
* A plugin that keeps re-registering from the SAME process is two live
|
|
7882
|
+
* clients in one process evicting each other (two module instances of
|
|
7883
|
+
* the plugin, each with its own socket), not a reconnect after a fault.
|
|
7884
|
+
* Each eviction fails every request in flight on the evicted socket, so
|
|
7885
|
+
* the symptom downstream is "Connection closed" on any call longer than
|
|
7886
|
+
* the client's reconnect backoff (Wibke Jnr, 2026-09-21: 2 evictions/s,
|
|
7887
|
+
* every per-business MYOB call dead). The dedupe above is still right
|
|
7888
|
+
* (a genuinely stale socket must be dropped), so make the flap loud
|
|
7889
|
+
* instead: one warning per plugin per minute once it exceeds the rate.
|
|
7890
|
+
*/
|
|
7891
|
+
noteSamePidReplacement(name, pid) {
|
|
7892
|
+
const key = `${name}:${String(pid)}`;
|
|
7893
|
+
const now = Date.now();
|
|
7894
|
+
for (const [k, ts] of this.samePidReplacements) {
|
|
7895
|
+
if (k === key) continue;
|
|
7896
|
+
if (now - (ts[ts.length - 1] ?? 0) >= 6e4) {
|
|
7897
|
+
this.samePidReplacements.delete(k);
|
|
7898
|
+
this.samePidFlapWarnedAt.delete(k);
|
|
7899
|
+
}
|
|
7900
|
+
}
|
|
7901
|
+
const times = (this.samePidReplacements.get(key) ?? []).filter((t) => now - t < SAME_PID_FLAP_WINDOW_MS);
|
|
7902
|
+
times.push(now);
|
|
7903
|
+
this.samePidReplacements.set(key, times);
|
|
7904
|
+
if (times.length < 10) return;
|
|
7905
|
+
if (now - (this.samePidFlapWarnedAt.get(key) ?? 0) < 6e4) return;
|
|
7906
|
+
this.samePidFlapWarnedAt.set(key, now);
|
|
7907
|
+
logger.warn({
|
|
7908
|
+
plugin: name,
|
|
7909
|
+
pid,
|
|
7910
|
+
replacements: times.length,
|
|
7911
|
+
windowMs: SAME_PID_FLAP_WINDOW_MS
|
|
7912
|
+
}, "IPC: plugin is re-registering from the same process in a loop — two IPC clients in one process are evicting each other; in-flight requests fail with \"Connection closed\"");
|
|
7913
|
+
}
|
|
7874
7914
|
closeOversizedConnection(conn) {
|
|
7875
7915
|
logger.warn({
|
|
7876
7916
|
connId: conn.id,
|
|
@@ -7923,6 +7963,7 @@ var IPCServer = class {
|
|
|
7923
7963
|
plugin: name,
|
|
7924
7964
|
pid
|
|
7925
7965
|
}, "IPC: closing stale duplicate connection (same PID)");
|
|
7966
|
+
this.noteSamePidReplacement(name, pid);
|
|
7926
7967
|
existing.socket.destroy();
|
|
7927
7968
|
staleIds.push(existingId);
|
|
7928
7969
|
} else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alfe.ai/gateway",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.5",
|
|
4
4
|
"description": "Alfe local gateway daemon — persistent control plane for agent integrations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"@alfe.ai/ai-proxy-local": "^0.0.17",
|
|
28
28
|
"@alfe.ai/config": "^0.4.1",
|
|
29
29
|
"@alfe.ai/integration-manifest": "^0.4.2",
|
|
30
|
-
"@alfe.ai/integrations": "^0.6.
|
|
30
|
+
"@alfe.ai/integrations": "^0.6.11",
|
|
31
31
|
"@alfe.ai/mcp-bundler": "^0.4.2"
|
|
32
32
|
},
|
|
33
33
|
"license": "UNLICENSED",
|