@xmoxmo/bncr 0.3.4 → 0.3.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/index.js +7 -3
- package/index.ts +6 -0
- package/openclaw.plugin.json +21 -0
- package/package.json +1 -1
- package/scripts/check-pack.mjs +97 -17
- package/scripts/check-register-drift.mjs +91 -65
- package/scripts/selfcheck.mjs +79 -3
- package/src/channel.ts +477 -635
- package/src/core/connection-capability.ts +2 -2
- package/src/core/connection-reachability.ts +106 -0
- package/src/core/dead-letter-diagnostics.ts +91 -0
- package/src/core/diagnostic-counters.ts +61 -0
- package/src/core/diagnostics.ts +9 -5
- package/src/core/downlink-health.ts +12 -7
- package/src/core/extended-diagnostics.ts +2 -0
- package/src/core/logging.ts +98 -0
- package/src/core/outbox-entry-builders.ts +13 -2
- package/src/core/persisted-outbox-entry.ts +53 -0
- package/src/core/probe.ts +33 -13
- package/src/core/register-trace.ts +48 -0
- package/src/core/status-meta.ts +77 -0
- package/src/core/status.ts +50 -57
- package/src/messaging/inbound/commands.ts +25 -86
- package/src/messaging/inbound/dispatch.ts +9 -36
- package/src/messaging/inbound/last-route.ts +46 -0
- package/src/messaging/inbound/native-command.ts +49 -0
- package/src/messaging/inbound/native-reply-delivery.ts +43 -0
- package/src/messaging/outbound/diagnostics.ts +221 -2
- package/src/messaging/outbound/reply-enqueue.ts +24 -1
- package/src/messaging/outbound/reply-target-policy.ts +4 -1
- package/src/messaging/outbound/send-params.ts +56 -0
- package/src/openclaw/runtime-surface.ts +29 -0
- package/src/plugin/gateway-methods.ts +2 -0
- package/src/plugin/status.ts +10 -4
- package/src/runtime/outbound-ack-timeout.ts +73 -0
- package/src/runtime/register-trace-runtime.ts +102 -0
- package/src/runtime/status-snapshots.ts +7 -3
- package/src/runtime/status-worker.ts +70 -11
package/dist/index.js
CHANGED
|
@@ -134,7 +134,6 @@ var BNCR_BRIDGE_OWNER = /* @__PURE__ */ Symbol.for("bncr.bridge.owner");
|
|
|
134
134
|
var BNCR_GATEWAY_RUNTIME = /* @__PURE__ */ Symbol.for("bncr.gateway.runtime");
|
|
135
135
|
var MODULE_EPOCH = `${process.pid}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
136
136
|
var runtime = null;
|
|
137
|
-
var activeServiceStop = null;
|
|
138
137
|
var identityIds = /* @__PURE__ */ new WeakMap();
|
|
139
138
|
var identitySeq = 0;
|
|
140
139
|
var tryExec = (command, args) => {
|
|
@@ -288,7 +287,9 @@ var loadRuntimeSync = () => {
|
|
|
288
287
|
return runtime;
|
|
289
288
|
} catch (error) {
|
|
290
289
|
const detail = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
|
|
291
|
-
throw new Error(
|
|
290
|
+
throw new Error(
|
|
291
|
+
`bncr failed to load channel runtime after dependency bootstrap from ${runtimeSourceDir}: ${detail}`
|
|
292
|
+
);
|
|
292
293
|
}
|
|
293
294
|
};
|
|
294
295
|
var getIdentityId = (obj, prefix) => {
|
|
@@ -375,6 +376,8 @@ var gatewayMethodDispatchers = {
|
|
|
375
376
|
"bncr.activity": (bridge, opts) => bridge.handleActivity(opts),
|
|
376
377
|
"bncr.ack": (bridge, opts) => bridge.handleAck(opts),
|
|
377
378
|
"bncr.diagnostics": (bridge, opts) => bridge.handleDiagnostics(opts),
|
|
379
|
+
"bncr.deadLetter.inspect": (bridge, opts) => bridge.handleDeadLetterInspect(opts),
|
|
380
|
+
"bncr.deadLetter.prune": (bridge, opts) => bridge.handleDeadLetterPrune(opts),
|
|
378
381
|
"bncr.file.init": (bridge, opts) => bridge.handleFileInit(opts),
|
|
379
382
|
"bncr.file.chunk": (bridge, opts) => bridge.handleFileChunk(opts),
|
|
380
383
|
"bncr.file.complete": (bridge, opts) => bridge.handleFileComplete(opts),
|
|
@@ -719,7 +722,6 @@ var plugin = {
|
|
|
719
722
|
},
|
|
720
723
|
stop: serviceStopHandler
|
|
721
724
|
});
|
|
722
|
-
activeServiceStop = serviceStopHandler;
|
|
723
725
|
gatewayRuntime.serviceRegistered = true;
|
|
724
726
|
gatewayRuntime.serviceOwnerApiInstanceId = apiInstanceId;
|
|
725
727
|
meta.service = true;
|
|
@@ -747,6 +749,8 @@ var plugin = {
|
|
|
747
749
|
ensureGatewayMethodRegistered(api, "bncr.activity", debugLog);
|
|
748
750
|
ensureGatewayMethodRegistered(api, "bncr.ack", debugLog);
|
|
749
751
|
ensureGatewayMethodRegistered(api, "bncr.diagnostics", debugLog);
|
|
752
|
+
ensureGatewayMethodRegistered(api, "bncr.deadLetter.inspect", debugLog);
|
|
753
|
+
ensureGatewayMethodRegistered(api, "bncr.deadLetter.prune", debugLog);
|
|
750
754
|
ensureGatewayMethodRegistered(api, "bncr.file.init", debugLog);
|
|
751
755
|
ensureGatewayMethodRegistered(api, "bncr.file.chunk", debugLog);
|
|
752
756
|
ensureGatewayMethodRegistered(api, "bncr.file.complete", debugLog);
|
package/index.ts
CHANGED
|
@@ -76,6 +76,8 @@ type GatewayMethodName =
|
|
|
76
76
|
| 'bncr.activity'
|
|
77
77
|
| 'bncr.ack'
|
|
78
78
|
| 'bncr.diagnostics'
|
|
79
|
+
| 'bncr.deadLetter.inspect'
|
|
80
|
+
| 'bncr.deadLetter.prune'
|
|
79
81
|
| 'bncr.file.init'
|
|
80
82
|
| 'bncr.file.chunk'
|
|
81
83
|
| 'bncr.file.complete'
|
|
@@ -405,6 +407,8 @@ const gatewayMethodDispatchers: Record<
|
|
|
405
407
|
'bncr.activity': (bridge, opts) => bridge.handleActivity(opts),
|
|
406
408
|
'bncr.ack': (bridge, opts) => bridge.handleAck(opts),
|
|
407
409
|
'bncr.diagnostics': (bridge, opts) => bridge.handleDiagnostics(opts),
|
|
410
|
+
'bncr.deadLetter.inspect': (bridge, opts) => bridge.handleDeadLetterInspect(opts),
|
|
411
|
+
'bncr.deadLetter.prune': (bridge, opts) => bridge.handleDeadLetterPrune(opts),
|
|
408
412
|
'bncr.file.init': (bridge, opts) => bridge.handleFileInit(opts),
|
|
409
413
|
'bncr.file.chunk': (bridge, opts) => bridge.handleFileChunk(opts),
|
|
410
414
|
'bncr.file.complete': (bridge, opts) => bridge.handleFileComplete(opts),
|
|
@@ -870,6 +874,8 @@ const plugin = {
|
|
|
870
874
|
ensureGatewayMethodRegistered(api, 'bncr.activity', debugLog);
|
|
871
875
|
ensureGatewayMethodRegistered(api, 'bncr.ack', debugLog);
|
|
872
876
|
ensureGatewayMethodRegistered(api, 'bncr.diagnostics', debugLog);
|
|
877
|
+
ensureGatewayMethodRegistered(api, 'bncr.deadLetter.inspect', debugLog);
|
|
878
|
+
ensureGatewayMethodRegistered(api, 'bncr.deadLetter.prune', debugLog);
|
|
873
879
|
ensureGatewayMethodRegistered(api, 'bncr.file.init', debugLog);
|
|
874
880
|
ensureGatewayMethodRegistered(api, 'bncr.file.chunk', debugLog);
|
|
875
881
|
ensureGatewayMethodRegistered(api, 'bncr.file.complete', debugLog);
|
package/openclaw.plugin.json
CHANGED
|
@@ -22,6 +22,22 @@
|
|
|
22
22
|
"type": "array",
|
|
23
23
|
"items": { "type": "string" }
|
|
24
24
|
},
|
|
25
|
+
"debug": {
|
|
26
|
+
"type": "object",
|
|
27
|
+
"additionalProperties": true,
|
|
28
|
+
"properties": {
|
|
29
|
+
"verbose": {
|
|
30
|
+
"type": "boolean",
|
|
31
|
+
"default": false,
|
|
32
|
+
"description": "Enable verbose debug logs for bncr channel runtime."
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"allowTool": {
|
|
37
|
+
"type": "boolean",
|
|
38
|
+
"default": false,
|
|
39
|
+
"description": "Allow tool messages to be forwarded when streaming is enabled. Defaults to false; only explicit true enables forwarding. When enabled, bncr also requests upstream tool summaries/results."
|
|
40
|
+
},
|
|
25
41
|
"requireMention": { "type": "boolean" },
|
|
26
42
|
"outboundRequireAck": { "type": "boolean" },
|
|
27
43
|
"accounts": {
|
|
@@ -81,6 +97,11 @@
|
|
|
81
97
|
"default": false,
|
|
82
98
|
"description": "Whether group messages must explicitly mention the bot before bncr handles them. Default false. Current version keeps this as a reserved field and does not enforce it yet."
|
|
83
99
|
},
|
|
100
|
+
"outboundRequireAck": {
|
|
101
|
+
"type": "boolean",
|
|
102
|
+
"default": true,
|
|
103
|
+
"description": "Whether outbound text waits for bncr.ack before leaving the retry queue. Default true to preserve current ack/dead-letter behavior."
|
|
104
|
+
},
|
|
84
105
|
"accounts": {
|
|
85
106
|
"type": "object",
|
|
86
107
|
"additionalProperties": {
|
package/package.json
CHANGED
package/scripts/check-pack.mjs
CHANGED
|
@@ -7,35 +7,115 @@ const __filename = fileURLToPath(import.meta.url);
|
|
|
7
7
|
const __dirname = path.dirname(__filename);
|
|
8
8
|
const root = path.resolve(__dirname, '..');
|
|
9
9
|
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
'
|
|
14
|
-
'package.json',
|
|
15
|
-
'scripts/selfcheck.mjs',
|
|
10
|
+
const requiredRootFiles = ['index.ts', 'openclaw.plugin.json'];
|
|
11
|
+
|
|
12
|
+
const requiredScriptFiles = [
|
|
13
|
+
'scripts/check-pack.mjs',
|
|
16
14
|
'scripts/check-register-drift.mjs',
|
|
15
|
+
'scripts/selfcheck.mjs',
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
const requiredSourceFiles = [
|
|
17
19
|
'src/channel.ts',
|
|
18
|
-
'src/
|
|
19
|
-
'src/
|
|
20
|
-
'src/
|
|
21
|
-
'src/
|
|
22
|
-
'src/
|
|
23
|
-
'src/
|
|
24
|
-
'src/
|
|
25
|
-
'src/
|
|
26
|
-
'src/
|
|
27
|
-
'src/
|
|
28
|
-
'src/
|
|
20
|
+
'src/core/types.ts',
|
|
21
|
+
'src/core/accounts.ts',
|
|
22
|
+
'src/core/connection-capability.ts',
|
|
23
|
+
'src/core/connection-reachability.ts',
|
|
24
|
+
'src/core/dead-letter-diagnostics.ts',
|
|
25
|
+
'src/core/diagnostic-counters.ts',
|
|
26
|
+
'src/core/diagnostics.ts',
|
|
27
|
+
'src/core/downlink-health.ts',
|
|
28
|
+
'src/core/extended-diagnostics.ts',
|
|
29
|
+
'src/core/file-ack.ts',
|
|
30
|
+
'src/core/file-transfer-payloads.ts',
|
|
31
|
+
'src/core/lease-state.ts',
|
|
32
|
+
'src/core/logging.ts',
|
|
33
|
+
'src/core/outbox-enqueue.ts',
|
|
34
|
+
'src/core/outbox-entry-builders.ts',
|
|
35
|
+
'src/core/outbox-file-transfer-bookkeeping.ts',
|
|
36
|
+
'src/core/outbox-file-transfer-failure.ts',
|
|
37
|
+
'src/core/outbox-file-transfer-guards.ts',
|
|
38
|
+
'src/core/outbox-file-transfer-prep.ts',
|
|
39
|
+
'src/core/outbox-file-transfer-success.ts',
|
|
40
|
+
'src/core/outbox-push-args.ts',
|
|
41
|
+
'src/core/outbox-queue.ts',
|
|
42
|
+
'src/core/outbox-summary.ts',
|
|
43
|
+
'src/core/outbox-text-push-failure.ts',
|
|
44
|
+
'src/core/outbox-text-push-guards.ts',
|
|
45
|
+
'src/core/outbox-text-push-prep.ts',
|
|
46
|
+
'src/core/outbox-text-push-success.ts',
|
|
47
|
+
'src/core/persisted-outbox-entry.ts',
|
|
48
|
+
'src/core/targets.ts',
|
|
49
|
+
'src/core/status.ts',
|
|
50
|
+
'src/core/status-meta.ts',
|
|
51
|
+
'src/core/probe.ts',
|
|
52
|
+
'src/core/config-schema.ts',
|
|
53
|
+
'src/core/policy.ts',
|
|
54
|
+
'src/core/permissions.ts',
|
|
55
|
+
'src/core/register-trace.ts',
|
|
56
|
+
'src/messaging/inbound/commands.ts',
|
|
57
|
+
'src/messaging/inbound/context-facts.ts',
|
|
58
|
+
'src/messaging/inbound/parse.ts',
|
|
59
|
+
'src/messaging/inbound/gate.ts',
|
|
60
|
+
'src/messaging/inbound/dispatch.ts',
|
|
61
|
+
'src/messaging/inbound/last-route.ts',
|
|
62
|
+
'src/messaging/inbound/native-command.ts',
|
|
63
|
+
'src/messaging/inbound/native-reply-delivery.ts',
|
|
64
|
+
'src/messaging/inbound/reply-config.ts',
|
|
65
|
+
'src/messaging/inbound/runtime-compat.ts',
|
|
66
|
+
'src/messaging/inbound/session-label.ts',
|
|
67
|
+
'src/messaging/outbound/send.ts',
|
|
68
|
+
'src/messaging/outbound/media.ts',
|
|
69
|
+
'src/messaging/outbound/actions.ts',
|
|
70
|
+
'src/messaging/outbound/build-send-action.ts',
|
|
71
|
+
'src/messaging/outbound/diagnostics.ts',
|
|
29
72
|
'src/messaging/outbound/durable-message-adapter.ts',
|
|
30
73
|
'src/messaging/outbound/durable-queue-adapter.ts',
|
|
74
|
+
'src/messaging/outbound/media-dedupe.ts',
|
|
75
|
+
'src/messaging/outbound/queue-selectors.ts',
|
|
76
|
+
'src/messaging/outbound/reasons.ts',
|
|
77
|
+
'src/messaging/outbound/reply-enqueue.ts',
|
|
78
|
+
'src/messaging/outbound/reply-target-policy.ts',
|
|
79
|
+
'src/messaging/outbound/retry-policy.ts',
|
|
80
|
+
'src/messaging/outbound/send-params.ts',
|
|
81
|
+
'src/messaging/outbound/session-route.ts',
|
|
82
|
+
'src/messaging/outbound/target-resolver.ts',
|
|
31
83
|
'src/openclaw/config-runtime.ts',
|
|
32
84
|
'src/openclaw/inbound-session-runtime.ts',
|
|
33
85
|
'src/openclaw/ingress-runtime.ts',
|
|
34
86
|
'src/openclaw/media-runtime.ts',
|
|
35
87
|
'src/openclaw/reply-runtime.ts',
|
|
36
88
|
'src/openclaw/routing-runtime.ts',
|
|
89
|
+
'src/openclaw/runtime-surface.ts',
|
|
37
90
|
'src/openclaw/sdk-helpers.ts',
|
|
38
91
|
'src/openclaw/session-route-runtime.ts',
|
|
92
|
+
'src/plugin/capabilities.ts',
|
|
93
|
+
'src/plugin/config.ts',
|
|
94
|
+
'src/plugin/gateway-methods.ts',
|
|
95
|
+
'src/plugin/gateway-runtime.ts',
|
|
96
|
+
'src/plugin/message-policy.ts',
|
|
97
|
+
'src/plugin/message-send.ts',
|
|
98
|
+
'src/plugin/messaging.ts',
|
|
99
|
+
'src/plugin/meta.ts',
|
|
100
|
+
'src/plugin/outbound.ts',
|
|
101
|
+
'src/plugin/setup.ts',
|
|
102
|
+
'src/plugin/status.ts',
|
|
103
|
+
'src/runtime/log-dedupe.ts',
|
|
104
|
+
'src/runtime/outbound-ack-timeout.ts',
|
|
105
|
+
'src/runtime/outbound-flags.ts',
|
|
106
|
+
'src/runtime/outbox-transitions.ts',
|
|
107
|
+
'src/runtime/register-trace-runtime.ts',
|
|
108
|
+
'src/runtime/status-snapshots.ts',
|
|
109
|
+
'src/runtime/status-worker.ts',
|
|
110
|
+
];
|
|
111
|
+
|
|
112
|
+
const requiredPackFiles = [
|
|
113
|
+
'LICENSE',
|
|
114
|
+
'README.md',
|
|
115
|
+
'package.json',
|
|
116
|
+
...requiredRootFiles,
|
|
117
|
+
...requiredScriptFiles,
|
|
118
|
+
...requiredSourceFiles,
|
|
39
119
|
];
|
|
40
120
|
|
|
41
121
|
const pkg = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8'));
|
|
@@ -1,39 +1,48 @@
|
|
|
1
1
|
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
2
3
|
|
|
3
4
|
const readNumber = (value, fallback) => {
|
|
4
5
|
const n = Number(value);
|
|
5
6
|
return Number.isFinite(n) ? n : fallback;
|
|
6
7
|
};
|
|
7
8
|
|
|
8
|
-
const
|
|
9
|
-
const
|
|
9
|
+
const readText = (value, fallback) => {
|
|
10
|
+
const text = String(value ?? '').trim();
|
|
11
|
+
return text || fallback;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const DEFAULT_OPTIONS = {
|
|
10
15
|
durationSec: 300,
|
|
11
16
|
intervalSec: 15,
|
|
12
17
|
accountId: 'Primary',
|
|
13
18
|
gatewayBin: 'openclaw',
|
|
14
19
|
};
|
|
15
20
|
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
);
|
|
27
|
-
process.exit(0);
|
|
21
|
+
export function parseCheckRegisterDriftOptions(args, defaults = DEFAULT_OPTIONS) {
|
|
22
|
+
const options = { ...defaults };
|
|
23
|
+
|
|
24
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
25
|
+
const arg = args[i];
|
|
26
|
+
if (arg === '--duration-sec') options.durationSec = readNumber(args[++i], options.durationSec);
|
|
27
|
+
else if (arg === '--interval-sec')
|
|
28
|
+
options.intervalSec = readNumber(args[++i], options.intervalSec);
|
|
29
|
+
else if (arg === '--account-id') options.accountId = readText(args[++i], options.accountId);
|
|
30
|
+
else if (arg === '--gateway-bin') options.gatewayBin = readText(args[++i], options.gatewayBin);
|
|
31
|
+
else if (arg === '--help' || arg === '-h') options.help = true;
|
|
28
32
|
}
|
|
33
|
+
|
|
34
|
+
return options;
|
|
29
35
|
}
|
|
30
36
|
|
|
31
|
-
|
|
32
|
-
|
|
37
|
+
const printHelp = () => {
|
|
38
|
+
console.log(
|
|
39
|
+
'Usage: node ./scripts/check-register-drift.mjs [--duration-sec 300] [--interval-sec 15] [--account-id Primary] [--gateway-bin openclaw]\n\nSamples bncr.diagnostics over time and reports whether register counters drift after warmup.',
|
|
40
|
+
);
|
|
41
|
+
};
|
|
33
42
|
|
|
34
43
|
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
35
44
|
|
|
36
|
-
const fetchDiagnostics = () => {
|
|
45
|
+
const fetchDiagnostics = (options) => {
|
|
37
46
|
const raw = execFileSync(
|
|
38
47
|
options.gatewayBin,
|
|
39
48
|
[
|
|
@@ -63,55 +72,72 @@ const fetchDiagnostics = () => {
|
|
|
63
72
|
};
|
|
64
73
|
};
|
|
65
74
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
75
|
+
export async function runCheckRegisterDrift(options) {
|
|
76
|
+
if (options.durationSec <= 0) throw new Error('durationSec must be > 0');
|
|
77
|
+
if (options.intervalSec <= 0) throw new Error('intervalSec must be > 0');
|
|
78
|
+
|
|
79
|
+
const startedAt = Date.now();
|
|
80
|
+
const samples = [];
|
|
81
|
+
const deadline = startedAt + options.durationSec * 1000;
|
|
82
|
+
|
|
83
|
+
while (true) {
|
|
84
|
+
const sample = fetchDiagnostics(options);
|
|
85
|
+
samples.push(sample);
|
|
86
|
+
const nextAt = Date.now() + options.intervalSec * 1000;
|
|
87
|
+
if (nextAt > deadline) break;
|
|
88
|
+
await sleep(Math.max(0, nextAt - Date.now()));
|
|
89
|
+
}
|
|
69
90
|
|
|
70
|
-
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
91
|
+
const first = samples[0] || {};
|
|
92
|
+
const last = samples[samples.length - 1] || {};
|
|
93
|
+
const deltaRegisterCount = (last.registerCount ?? 0) - (first.registerCount ?? 0);
|
|
94
|
+
const deltaApiGeneration = (last.apiGeneration ?? 0) - (first.apiGeneration ?? 0);
|
|
95
|
+
const deltaPostWarmupRegisterCount =
|
|
96
|
+
(last.postWarmupRegisterCount ?? 0) - (first.postWarmupRegisterCount ?? 0);
|
|
97
|
+
const historicalWarmupExternalDrift = Boolean(first.unexpectedRegisterAfterWarmup);
|
|
98
|
+
const newWarmupExternalDriftDuringWindow = deltaPostWarmupRegisterCount > 0;
|
|
99
|
+
const newDriftDuringWindow =
|
|
100
|
+
deltaRegisterCount > 0 || deltaApiGeneration > 0 || newWarmupExternalDriftDuringWindow;
|
|
101
|
+
const driftDetected = historicalWarmupExternalDrift || newDriftDuringWindow;
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
ok: true,
|
|
105
|
+
accountId: options.accountId,
|
|
106
|
+
durationSec: options.durationSec,
|
|
107
|
+
intervalSec: options.intervalSec,
|
|
108
|
+
startedAt,
|
|
109
|
+
endedAt: Date.now(),
|
|
110
|
+
sampleCount: samples.length,
|
|
111
|
+
first,
|
|
112
|
+
last,
|
|
113
|
+
delta: {
|
|
114
|
+
registerCount: deltaRegisterCount,
|
|
115
|
+
apiGeneration: deltaApiGeneration,
|
|
116
|
+
postWarmupRegisterCount: deltaPostWarmupRegisterCount,
|
|
117
|
+
},
|
|
118
|
+
historicalWarmupExternalDrift,
|
|
119
|
+
newWarmupExternalDriftDuringWindow,
|
|
120
|
+
newDriftDuringWindow,
|
|
121
|
+
driftDetected,
|
|
122
|
+
conclusion: newDriftDuringWindow
|
|
123
|
+
? 'new register drift was observed during this sampling window'
|
|
124
|
+
: historicalWarmupExternalDrift
|
|
125
|
+
? 'no new drift during this window, but warmup-external drift had already happened before sampling began'
|
|
126
|
+
: 'register counters stayed stable during this window and no warmup-external drift was flagged',
|
|
127
|
+
samples,
|
|
128
|
+
};
|
|
76
129
|
}
|
|
77
130
|
|
|
78
|
-
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
deltaRegisterCount > 0 || deltaApiGeneration > 0 || newWarmupExternalDriftDuringWindow;
|
|
88
|
-
const driftDetected = historicalWarmupExternalDrift || newDriftDuringWindow;
|
|
89
|
-
|
|
90
|
-
const result = {
|
|
91
|
-
ok: true,
|
|
92
|
-
accountId: options.accountId,
|
|
93
|
-
durationSec: options.durationSec,
|
|
94
|
-
intervalSec: options.intervalSec,
|
|
95
|
-
startedAt,
|
|
96
|
-
endedAt: Date.now(),
|
|
97
|
-
sampleCount: samples.length,
|
|
98
|
-
first,
|
|
99
|
-
last,
|
|
100
|
-
delta: {
|
|
101
|
-
registerCount: deltaRegisterCount,
|
|
102
|
-
apiGeneration: deltaApiGeneration,
|
|
103
|
-
postWarmupRegisterCount: deltaPostWarmupRegisterCount,
|
|
104
|
-
},
|
|
105
|
-
historicalWarmupExternalDrift,
|
|
106
|
-
newWarmupExternalDriftDuringWindow,
|
|
107
|
-
newDriftDuringWindow,
|
|
108
|
-
driftDetected,
|
|
109
|
-
conclusion: newDriftDuringWindow
|
|
110
|
-
? 'new register drift was observed during this sampling window'
|
|
111
|
-
: historicalWarmupExternalDrift
|
|
112
|
-
? 'no new drift during this window, but warmup-external drift had already happened before sampling began'
|
|
113
|
-
: 'register counters stayed stable during this window and no warmup-external drift was flagged',
|
|
114
|
-
samples,
|
|
115
|
-
};
|
|
131
|
+
async function main() {
|
|
132
|
+
const options = parseCheckRegisterDriftOptions(process.argv.slice(2));
|
|
133
|
+
if (options.help) {
|
|
134
|
+
printHelp();
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
console.log(JSON.stringify(await runCheckRegisterDrift(options), null, 2));
|
|
139
|
+
}
|
|
116
140
|
|
|
117
|
-
|
|
141
|
+
if (process.argv[1] && fileURLToPath(import.meta.url) === process.argv[1]) {
|
|
142
|
+
await main();
|
|
143
|
+
}
|
package/scripts/selfcheck.mjs
CHANGED
|
@@ -8,36 +8,104 @@ const __dirname = path.dirname(__filename);
|
|
|
8
8
|
const root = path.resolve(__dirname, '..');
|
|
9
9
|
const require = createRequire(import.meta.url);
|
|
10
10
|
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
const requiredRootFiles = ['index.ts', 'openclaw.plugin.json'];
|
|
12
|
+
|
|
13
|
+
const requiredSourceFiles = [
|
|
14
14
|
'src/channel.ts',
|
|
15
15
|
'src/core/types.ts',
|
|
16
16
|
'src/core/accounts.ts',
|
|
17
|
+
'src/core/connection-capability.ts',
|
|
18
|
+
'src/core/connection-reachability.ts',
|
|
19
|
+
'src/core/dead-letter-diagnostics.ts',
|
|
20
|
+
'src/core/diagnostic-counters.ts',
|
|
21
|
+
'src/core/diagnostics.ts',
|
|
22
|
+
'src/core/downlink-health.ts',
|
|
23
|
+
'src/core/extended-diagnostics.ts',
|
|
24
|
+
'src/core/file-ack.ts',
|
|
25
|
+
'src/core/file-transfer-payloads.ts',
|
|
26
|
+
'src/core/lease-state.ts',
|
|
27
|
+
'src/core/logging.ts',
|
|
28
|
+
'src/core/outbox-enqueue.ts',
|
|
29
|
+
'src/core/outbox-entry-builders.ts',
|
|
30
|
+
'src/core/outbox-file-transfer-bookkeeping.ts',
|
|
31
|
+
'src/core/outbox-file-transfer-failure.ts',
|
|
32
|
+
'src/core/outbox-file-transfer-guards.ts',
|
|
33
|
+
'src/core/outbox-file-transfer-prep.ts',
|
|
34
|
+
'src/core/outbox-file-transfer-success.ts',
|
|
35
|
+
'src/core/outbox-push-args.ts',
|
|
36
|
+
'src/core/outbox-queue.ts',
|
|
37
|
+
'src/core/outbox-summary.ts',
|
|
38
|
+
'src/core/outbox-text-push-failure.ts',
|
|
39
|
+
'src/core/outbox-text-push-guards.ts',
|
|
40
|
+
'src/core/outbox-text-push-prep.ts',
|
|
41
|
+
'src/core/outbox-text-push-success.ts',
|
|
42
|
+
'src/core/persisted-outbox-entry.ts',
|
|
17
43
|
'src/core/targets.ts',
|
|
18
44
|
'src/core/status.ts',
|
|
45
|
+
'src/core/status-meta.ts',
|
|
19
46
|
'src/core/probe.ts',
|
|
20
47
|
'src/core/config-schema.ts',
|
|
21
48
|
'src/core/policy.ts',
|
|
22
49
|
'src/core/permissions.ts',
|
|
50
|
+
'src/core/register-trace.ts',
|
|
51
|
+
'src/messaging/inbound/commands.ts',
|
|
52
|
+
'src/messaging/inbound/context-facts.ts',
|
|
23
53
|
'src/messaging/inbound/parse.ts',
|
|
24
54
|
'src/messaging/inbound/gate.ts',
|
|
25
55
|
'src/messaging/inbound/dispatch.ts',
|
|
56
|
+
'src/messaging/inbound/last-route.ts',
|
|
57
|
+
'src/messaging/inbound/native-command.ts',
|
|
58
|
+
'src/messaging/inbound/native-reply-delivery.ts',
|
|
59
|
+
'src/messaging/inbound/reply-config.ts',
|
|
60
|
+
'src/messaging/inbound/runtime-compat.ts',
|
|
61
|
+
'src/messaging/inbound/session-label.ts',
|
|
26
62
|
'src/messaging/outbound/send.ts',
|
|
27
63
|
'src/messaging/outbound/media.ts',
|
|
28
64
|
'src/messaging/outbound/actions.ts',
|
|
65
|
+
'src/messaging/outbound/build-send-action.ts',
|
|
66
|
+
'src/messaging/outbound/diagnostics.ts',
|
|
29
67
|
'src/messaging/outbound/durable-message-adapter.ts',
|
|
30
68
|
'src/messaging/outbound/durable-queue-adapter.ts',
|
|
69
|
+
'src/messaging/outbound/media-dedupe.ts',
|
|
70
|
+
'src/messaging/outbound/queue-selectors.ts',
|
|
71
|
+
'src/messaging/outbound/reasons.ts',
|
|
72
|
+
'src/messaging/outbound/reply-enqueue.ts',
|
|
73
|
+
'src/messaging/outbound/reply-target-policy.ts',
|
|
74
|
+
'src/messaging/outbound/retry-policy.ts',
|
|
75
|
+
'src/messaging/outbound/send-params.ts',
|
|
76
|
+
'src/messaging/outbound/session-route.ts',
|
|
77
|
+
'src/messaging/outbound/target-resolver.ts',
|
|
31
78
|
'src/openclaw/config-runtime.ts',
|
|
32
79
|
'src/openclaw/inbound-session-runtime.ts',
|
|
33
80
|
'src/openclaw/ingress-runtime.ts',
|
|
34
81
|
'src/openclaw/media-runtime.ts',
|
|
35
82
|
'src/openclaw/reply-runtime.ts',
|
|
36
83
|
'src/openclaw/routing-runtime.ts',
|
|
84
|
+
'src/openclaw/runtime-surface.ts',
|
|
37
85
|
'src/openclaw/sdk-helpers.ts',
|
|
38
86
|
'src/openclaw/session-route-runtime.ts',
|
|
87
|
+
'src/plugin/capabilities.ts',
|
|
88
|
+
'src/plugin/config.ts',
|
|
89
|
+
'src/plugin/gateway-methods.ts',
|
|
90
|
+
'src/plugin/gateway-runtime.ts',
|
|
91
|
+
'src/plugin/message-policy.ts',
|
|
92
|
+
'src/plugin/message-send.ts',
|
|
93
|
+
'src/plugin/messaging.ts',
|
|
94
|
+
'src/plugin/meta.ts',
|
|
95
|
+
'src/plugin/outbound.ts',
|
|
96
|
+
'src/plugin/setup.ts',
|
|
97
|
+
'src/plugin/status.ts',
|
|
98
|
+
'src/runtime/log-dedupe.ts',
|
|
99
|
+
'src/runtime/outbound-ack-timeout.ts',
|
|
100
|
+
'src/runtime/outbound-flags.ts',
|
|
101
|
+
'src/runtime/outbox-transitions.ts',
|
|
102
|
+
'src/runtime/register-trace-runtime.ts',
|
|
103
|
+
'src/runtime/status-snapshots.ts',
|
|
104
|
+
'src/runtime/status-worker.ts',
|
|
39
105
|
];
|
|
40
106
|
|
|
107
|
+
const requiredFiles = [...requiredRootFiles, ...requiredSourceFiles];
|
|
108
|
+
|
|
41
109
|
const readPackageVersion = () => {
|
|
42
110
|
const pkgPath = path.join(root, 'package.json');
|
|
43
111
|
const raw = fs.readFileSync(pkgPath, 'utf8');
|
|
@@ -46,12 +114,20 @@ const readPackageVersion = () => {
|
|
|
46
114
|
};
|
|
47
115
|
|
|
48
116
|
const requiredOpenClawSdkSubpaths = [
|
|
117
|
+
'openclaw/plugin-sdk',
|
|
118
|
+
'openclaw/plugin-sdk/boolean-param',
|
|
49
119
|
'openclaw/plugin-sdk/channel-outbound',
|
|
120
|
+
'openclaw/plugin-sdk/channel-ingress-runtime',
|
|
50
121
|
'openclaw/plugin-sdk/channel-message',
|
|
51
122
|
'openclaw/plugin-sdk/routing',
|
|
52
123
|
'openclaw/plugin-sdk/conversation-runtime',
|
|
53
124
|
'openclaw/plugin-sdk/session-store-runtime',
|
|
54
125
|
'openclaw/plugin-sdk/core',
|
|
126
|
+
'openclaw/plugin-sdk/json-store',
|
|
127
|
+
'openclaw/plugin-sdk/param-readers',
|
|
128
|
+
'openclaw/plugin-sdk/security-runtime',
|
|
129
|
+
'openclaw/plugin-sdk/status-helpers',
|
|
130
|
+
'openclaw/plugin-sdk/tool-send',
|
|
55
131
|
];
|
|
56
132
|
|
|
57
133
|
const resolveOpenClawSdkSubpaths = () => {
|