@xmoxmo/bncr 0.3.1 → 0.3.3
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/README.md +15 -1
- package/dist/index.js +9 -2
- package/index.ts +12 -2
- package/package.json +1 -1
- package/scripts/selfcheck.mjs +30 -2
- package/src/messaging/outbound/durable-message-adapter.ts +2 -2
package/README.md
CHANGED
|
@@ -193,6 +193,20 @@ openclaw gateway call message.action --params '{
|
|
|
193
193
|
|
|
194
194
|
后续如果在其他 OpenClaw 版本上完成验证,应继续在本节追加对应版本的验证过程与结论,不直接外推复用 `2026.5.18` 的验证口径。
|
|
195
195
|
|
|
196
|
+
### 2026.6.1 验证说明
|
|
197
|
+
|
|
198
|
+
以下口径已在 OpenClaw `2026.6.1` 与 bncr `0.3.2` 上完成基础验证:
|
|
199
|
+
|
|
200
|
+
1. 普通文本入站与 assistant 文本回复正常。
|
|
201
|
+
2. Agent 回复中的图片附件可通过 `MEDIA:<path>` 投递。
|
|
202
|
+
3. Agent 回复中的 `ogg(opus)` voice 附件可通过 `MEDIA:<path>` 搭配 voice 发送提示投递。
|
|
203
|
+
4. 入站 prompt 中只出现 OpenClaw 官方 `Conversation info` / `Sender` untrusted metadata,未重复注入 bncr 自定义 context block。
|
|
204
|
+
|
|
205
|
+
仍需分开判断:
|
|
206
|
+
|
|
207
|
+
- `MEDIA:<path>` 成功代表宿主 reply-media / attachment 链路和 bncr 下行媒体投递在该场景下可用。
|
|
208
|
+
- `message.action` / `send` 仍应作为显式目标发送链单独验证,特别是跨会话、跨账号、文件传输 ACK 与 outbox 重试场景。
|
|
209
|
+
|
|
196
210
|
---
|
|
197
211
|
|
|
198
212
|
## 8. 状态与诊断
|
|
@@ -257,7 +271,7 @@ npm pack
|
|
|
257
271
|
用途:
|
|
258
272
|
|
|
259
273
|
- `npm test`:跑回归测试
|
|
260
|
-
- `npm run selfcheck
|
|
274
|
+
- `npm run selfcheck`:检查插件骨架是否完整,并验证关键 OpenClaw SDK subpath 可解析
|
|
261
275
|
- `npm run check-pack`:执行 `npm pack --dry-run --json`,确认发布包包含关键入口与 OpenClaw adapter 文件
|
|
262
276
|
- `npm pack`:确认当前版本可正常打包
|
|
263
277
|
- `npm run check-register-drift -- --duration-sec 300 --interval-sec 15`:静置采样 `bncr.diagnostics`,观察 `registerCount / apiGeneration / postWarmupRegisterCount` 是否在 warmup 后继续增长
|
package/dist/index.js
CHANGED
|
@@ -251,6 +251,13 @@ var ensurePluginNodeModulesLink = (targetRoot) => {
|
|
|
251
251
|
}
|
|
252
252
|
fs.symlinkSync(targetRoot, linkPath, linkType);
|
|
253
253
|
};
|
|
254
|
+
var runtimeSourceDir = (() => {
|
|
255
|
+
const direct = path.join(pluginDir, "src");
|
|
256
|
+
if (fs.existsSync(path.join(direct, "channel.ts"))) return direct;
|
|
257
|
+
const parent = path.join(pluginDir, "..", "src");
|
|
258
|
+
if (fs.existsSync(path.join(parent, "channel.ts"))) return parent;
|
|
259
|
+
return direct;
|
|
260
|
+
})();
|
|
254
261
|
var ensureOpenClawSdkResolution = () => {
|
|
255
262
|
if (canResolveSdkCore()) return;
|
|
256
263
|
let lastError = "";
|
|
@@ -273,7 +280,7 @@ var loadRuntimeSync = () => {
|
|
|
273
280
|
if (runtime) return runtime;
|
|
274
281
|
ensureOpenClawSdkResolution();
|
|
275
282
|
try {
|
|
276
|
-
const mod = pluginRequire("
|
|
283
|
+
const mod = pluginRequire(path.join(runtimeSourceDir, "channel.ts"));
|
|
277
284
|
runtime = {
|
|
278
285
|
createBncrBridge: mod.createBncrBridge,
|
|
279
286
|
createBncrChannelPlugin: mod.createBncrChannelPlugin
|
|
@@ -281,7 +288,7 @@ var loadRuntimeSync = () => {
|
|
|
281
288
|
return runtime;
|
|
282
289
|
} catch (error) {
|
|
283
290
|
const detail = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
|
|
284
|
-
throw new Error(`bncr failed to load channel runtime after dependency bootstrap: ${detail}`);
|
|
291
|
+
throw new Error(`bncr failed to load channel runtime after dependency bootstrap from ${runtimeSourceDir}: ${detail}`);
|
|
285
292
|
}
|
|
286
293
|
};
|
|
287
294
|
var getIdentityId = (obj, prefix) => {
|
package/index.ts
CHANGED
|
@@ -251,6 +251,16 @@ const ensurePluginNodeModulesLink = (targetRoot: string) => {
|
|
|
251
251
|
fs.symlinkSync(targetRoot, linkPath, linkType as fs.symlink.Type);
|
|
252
252
|
};
|
|
253
253
|
|
|
254
|
+
const runtimeSourceDir = (() => {
|
|
255
|
+
const direct = path.join(pluginDir, 'src');
|
|
256
|
+
if (fs.existsSync(path.join(direct, 'channel.ts'))) return direct;
|
|
257
|
+
|
|
258
|
+
const parent = path.join(pluginDir, '..', 'src');
|
|
259
|
+
if (fs.existsSync(path.join(parent, 'channel.ts'))) return parent;
|
|
260
|
+
|
|
261
|
+
return direct;
|
|
262
|
+
})();
|
|
263
|
+
|
|
254
264
|
const ensureOpenClawSdkResolution = () => {
|
|
255
265
|
if (canResolveSdkCore()) return;
|
|
256
266
|
|
|
@@ -279,7 +289,7 @@ const loadRuntimeSync = (): LoadedRuntime => {
|
|
|
279
289
|
if (runtime) return runtime;
|
|
280
290
|
ensureOpenClawSdkResolution();
|
|
281
291
|
try {
|
|
282
|
-
const mod = pluginRequire('
|
|
292
|
+
const mod = pluginRequire(path.join(runtimeSourceDir, 'channel.ts')) as ChannelModule;
|
|
283
293
|
runtime = {
|
|
284
294
|
createBncrBridge: mod.createBncrBridge,
|
|
285
295
|
createBncrChannelPlugin: mod.createBncrChannelPlugin,
|
|
@@ -287,7 +297,7 @@ const loadRuntimeSync = (): LoadedRuntime => {
|
|
|
287
297
|
return runtime;
|
|
288
298
|
} catch (error) {
|
|
289
299
|
const detail = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
|
|
290
|
-
throw new Error(`bncr failed to load channel runtime after dependency bootstrap: ${detail}`);
|
|
300
|
+
throw new Error(`bncr failed to load channel runtime after dependency bootstrap from ${runtimeSourceDir}: ${detail}`);
|
|
291
301
|
}
|
|
292
302
|
};
|
|
293
303
|
|
package/package.json
CHANGED
package/scripts/selfcheck.mjs
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
2
3
|
import path from 'node:path';
|
|
3
4
|
import { fileURLToPath } from 'node:url';
|
|
4
5
|
|
|
5
6
|
const __filename = fileURLToPath(import.meta.url);
|
|
6
7
|
const __dirname = path.dirname(__filename);
|
|
7
8
|
const root = path.resolve(__dirname, '..');
|
|
9
|
+
const require = createRequire(import.meta.url);
|
|
8
10
|
|
|
9
11
|
const requiredFiles = [
|
|
10
12
|
'index.ts',
|
|
@@ -43,6 +45,29 @@ const readPackageVersion = () => {
|
|
|
43
45
|
return typeof pkg?.version === 'string' ? pkg.version.trim() : '';
|
|
44
46
|
};
|
|
45
47
|
|
|
48
|
+
const requiredOpenClawSdkSubpaths = [
|
|
49
|
+
'openclaw/plugin-sdk/channel-outbound',
|
|
50
|
+
'openclaw/plugin-sdk/channel-message',
|
|
51
|
+
'openclaw/plugin-sdk/routing',
|
|
52
|
+
'openclaw/plugin-sdk/conversation-runtime',
|
|
53
|
+
'openclaw/plugin-sdk/session-store-runtime',
|
|
54
|
+
'openclaw/plugin-sdk/core',
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
const resolveOpenClawSdkSubpaths = () => {
|
|
58
|
+
return requiredOpenClawSdkSubpaths.map((specifier) => {
|
|
59
|
+
try {
|
|
60
|
+
return { specifier, ok: true, path: require.resolve(specifier) };
|
|
61
|
+
} catch (err) {
|
|
62
|
+
return {
|
|
63
|
+
specifier,
|
|
64
|
+
ok: false,
|
|
65
|
+
error: err && typeof err === 'object' && 'code' in err ? err.code : String(err),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
|
|
46
71
|
const validateVersionPolicy = (version) => {
|
|
47
72
|
const match = version.match(/^(\d+)\.(\d+)\.(\d+)$/);
|
|
48
73
|
if (!match) {
|
|
@@ -68,14 +93,17 @@ const validateVersionPolicy = (version) => {
|
|
|
68
93
|
const missing = requiredFiles.filter((rel) => !fs.existsSync(path.join(root, rel)));
|
|
69
94
|
const version = readPackageVersion();
|
|
70
95
|
const versionPolicy = validateVersionPolicy(version);
|
|
96
|
+
const sdkSubpaths = resolveOpenClawSdkSubpaths();
|
|
97
|
+
const missingSdkSubpaths = sdkSubpaths.filter((entry) => !entry.ok);
|
|
71
98
|
const result = {
|
|
72
|
-
ok: missing.length === 0 && versionPolicy.ok,
|
|
99
|
+
ok: missing.length === 0 && versionPolicy.ok && missingSdkSubpaths.length === 0,
|
|
73
100
|
checkedRoot: root,
|
|
74
101
|
requiredCount: requiredFiles.length,
|
|
75
102
|
missing,
|
|
76
103
|
version,
|
|
77
104
|
versionPolicy,
|
|
105
|
+
sdkSubpaths,
|
|
78
106
|
};
|
|
79
107
|
|
|
80
108
|
console.log(JSON.stringify(result, null, 2));
|
|
81
|
-
if (missing.length > 0 || !versionPolicy.ok) process.exit(1);
|
|
109
|
+
if (missing.length > 0 || !versionPolicy.ok || missingSdkSubpaths.length > 0) process.exit(1);
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { defineChannelMessageAdapter } from 'openclaw/plugin-sdk/channel-
|
|
1
|
+
import { defineChannelMessageAdapter } from 'openclaw/plugin-sdk/channel-message';
|
|
2
2
|
import type {
|
|
3
3
|
ChannelMessageAdapterShape,
|
|
4
4
|
ChannelMessageSendMediaContext,
|
|
5
5
|
ChannelMessageSendPayloadContext,
|
|
6
6
|
ChannelMessageSendResult,
|
|
7
7
|
ChannelMessageSendTextContext,
|
|
8
|
-
} from 'openclaw/plugin-sdk/channel-
|
|
8
|
+
} from 'openclaw/plugin-sdk/channel-message';
|
|
9
9
|
|
|
10
10
|
import { buildFileTransferOutboxEntry, buildTextOutboxEntry } from '../../core/outbox-entry-builders.ts';
|
|
11
11
|
import type { BncrRoute, OutboxEntry } from '../../core/types.ts';
|