libp2p-mesh 2026.6.1 → 2026.6.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/dist/index.js +10 -0
- package/dist/src/inbound-delivery.d.ts +5 -3
- package/dist/src/inbound-delivery.js +35 -77
- package/dist/src/plugin.js +6 -2
- package/dist/src/types.d.ts +7 -0
- package/index.ts +10 -0
- package/openclaw.plugin.json +21 -0
- package/package.json +1 -1
- package/src/inbound-delivery.ts +47 -91
- package/src/plugin.ts +6 -2
- package/src/types.ts +7 -0
package/dist/index.js
CHANGED
|
@@ -99,6 +99,16 @@ function createLibp2pMeshConfigSchema() {
|
|
|
99
99
|
items: { type: "string" },
|
|
100
100
|
description: "Multiaddrs of relay nodes to reserve a slot on (each entry must end in /p2p/<peer-id>).",
|
|
101
101
|
},
|
|
102
|
+
relayChannel: {
|
|
103
|
+
type: "string",
|
|
104
|
+
deprecated: true,
|
|
105
|
+
description: "Deprecated compatibility field from older libp2p-mesh versions. Use relayList for relay nodes.",
|
|
106
|
+
},
|
|
107
|
+
relayAccountId: {
|
|
108
|
+
type: "string",
|
|
109
|
+
deprecated: true,
|
|
110
|
+
description: "Deprecated compatibility field from older libp2p-mesh versions. This value is ignored.",
|
|
111
|
+
},
|
|
102
112
|
discoverRelays: {
|
|
103
113
|
type: "number",
|
|
104
114
|
default: 0,
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
import type { ChannelOutboundAdapter, OpenClawConfig } from "openclaw/plugin-sdk/core";
|
|
1
2
|
import type { InboundDeliveryAdapter } from "./types.js";
|
|
2
3
|
export type DeliveryLogger = {
|
|
3
4
|
info?: (message: string) => void;
|
|
4
5
|
debug?: (message: string) => void;
|
|
5
6
|
warn?: (message: string) => void;
|
|
6
7
|
};
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
export type LoadChannelOutboundAdapter = (channel: string) => Promise<ChannelOutboundAdapter | undefined>;
|
|
9
|
+
export declare function createOpenClawRuntimeInboundDelivery(options: {
|
|
10
|
+
config: OpenClawConfig;
|
|
11
|
+
loadAdapter: LoadChannelOutboundAdapter;
|
|
10
12
|
logger?: DeliveryLogger;
|
|
11
13
|
}): InboundDeliveryAdapter;
|
|
@@ -1,83 +1,41 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const logger = options
|
|
1
|
+
function summarizeError(error) {
|
|
2
|
+
return error instanceof Error ? error.message : String(error);
|
|
3
|
+
}
|
|
4
|
+
export function createOpenClawRuntimeInboundDelivery(options) {
|
|
5
|
+
const { config, loadAdapter, logger } = options;
|
|
6
6
|
return {
|
|
7
|
-
deliver(request) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
request.text,
|
|
17
|
-
];
|
|
18
|
-
logger?.debug?.(`[libp2p-mesh] Forwarding inbound delivery via CLI: ${command} ${args.join(" ")}`);
|
|
19
|
-
return new Promise((resolve) => {
|
|
20
|
-
const child = spawn(command, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
21
|
-
const stdout = [];
|
|
22
|
-
const stderr = [];
|
|
23
|
-
let settled = false;
|
|
24
|
-
let timeout;
|
|
25
|
-
const finish = (result) => {
|
|
26
|
-
if (settled) {
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
settled = true;
|
|
30
|
-
if (timeout) {
|
|
31
|
-
clearTimeout(timeout);
|
|
32
|
-
}
|
|
33
|
-
resolve(result);
|
|
7
|
+
async deliver(request) {
|
|
8
|
+
logger?.debug?.(`[libp2p-mesh] Forwarding inbound delivery via runtime channel adapter: ${request.channel}/${request.target}`);
|
|
9
|
+
const adapter = await loadAdapter(request.channel);
|
|
10
|
+
if (!adapter?.sendText) {
|
|
11
|
+
return {
|
|
12
|
+
ok: false,
|
|
13
|
+
channel: request.channel,
|
|
14
|
+
target: request.target,
|
|
15
|
+
error: `channel ${request.channel} does not expose runtime text delivery`,
|
|
34
16
|
};
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
target: request.target,
|
|
42
|
-
error: `openclaw message send timed out after ${timeoutMs}ms`,
|
|
43
|
-
});
|
|
44
|
-
}, timeoutMs);
|
|
45
|
-
child.stdout.on("data", (chunk) => {
|
|
46
|
-
stdout.push(chunk);
|
|
47
|
-
});
|
|
48
|
-
child.stderr.on("data", (chunk) => {
|
|
49
|
-
stderr.push(chunk);
|
|
50
|
-
});
|
|
51
|
-
child.on("error", (err) => {
|
|
52
|
-
finish({
|
|
53
|
-
ok: false,
|
|
54
|
-
channel: request.channel,
|
|
55
|
-
target: request.target,
|
|
56
|
-
error: String(err),
|
|
57
|
-
});
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
await adapter.sendText({
|
|
20
|
+
cfg: config,
|
|
21
|
+
to: request.target,
|
|
22
|
+
text: request.text,
|
|
58
23
|
});
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
target: request.target,
|
|
75
|
-
error: stderrText ||
|
|
76
|
-
stdoutText ||
|
|
77
|
-
`openclaw message send exited with code ${code}`,
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
});
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
return {
|
|
27
|
+
ok: false,
|
|
28
|
+
channel: request.channel,
|
|
29
|
+
target: request.target,
|
|
30
|
+
error: summarizeError(error),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
logger?.info?.(`[libp2p-mesh] Delivered inbound message to ${request.channel}/${request.target}`);
|
|
34
|
+
return {
|
|
35
|
+
ok: true,
|
|
36
|
+
channel: request.channel,
|
|
37
|
+
target: request.target,
|
|
38
|
+
};
|
|
81
39
|
},
|
|
82
40
|
};
|
|
83
41
|
}
|
package/dist/src/plugin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createLibp2pMeshChannel } from "./channel.js";
|
|
2
2
|
import { handleP2PInbound } from "./inbound.js";
|
|
3
|
-
import {
|
|
3
|
+
import { createOpenClawRuntimeInboundDelivery } from "./inbound-delivery.js";
|
|
4
4
|
import { createInstancePeerStore } from "./instance-peer-store.js";
|
|
5
5
|
import { createInstanceRouter } from "./instance-router.js";
|
|
6
6
|
import { createMeshNetwork } from "./mesh.js";
|
|
@@ -14,7 +14,11 @@ export function registerLibp2pMesh(api) {
|
|
|
14
14
|
logger: api.logger,
|
|
15
15
|
});
|
|
16
16
|
const store = createInstancePeerStore({ logger: api.logger });
|
|
17
|
-
const delivery =
|
|
17
|
+
const delivery = createOpenClawRuntimeInboundDelivery({
|
|
18
|
+
config: api.config,
|
|
19
|
+
loadAdapter: api.runtime.channel.outbound.loadAdapter,
|
|
20
|
+
logger: api.logger,
|
|
21
|
+
});
|
|
18
22
|
const router = createInstanceRouter({
|
|
19
23
|
mesh,
|
|
20
24
|
store,
|
package/dist/src/types.d.ts
CHANGED
|
@@ -162,6 +162,13 @@ export interface MeshConfig {
|
|
|
162
162
|
* reservation open with each one so other peers can dial us through them.
|
|
163
163
|
*/
|
|
164
164
|
relayList?: string[];
|
|
165
|
+
/**
|
|
166
|
+
* Deprecated pre-2026.6 config keys kept so existing OpenClaw configs keep
|
|
167
|
+
* validating after upgrade. Relay selection is now configured with
|
|
168
|
+
* `relayList`; inbound display uses `inboundChannel`/`inboundTarget`.
|
|
169
|
+
*/
|
|
170
|
+
relayChannel?: string;
|
|
171
|
+
relayAccountId?: string;
|
|
165
172
|
/**
|
|
166
173
|
* Number of relays to auto-discover via content routing. Requires DHT.
|
|
167
174
|
* Default `0` (disabled). Set to e.g. `2` to look up public relays.
|
package/index.ts
CHANGED
|
@@ -101,6 +101,16 @@ function createLibp2pMeshConfigSchema(): OpenClawPluginConfigSchema {
|
|
|
101
101
|
items: { type: "string" },
|
|
102
102
|
description: "Multiaddrs of relay nodes to reserve a slot on (each entry must end in /p2p/<peer-id>).",
|
|
103
103
|
},
|
|
104
|
+
relayChannel: {
|
|
105
|
+
type: "string",
|
|
106
|
+
deprecated: true,
|
|
107
|
+
description: "Deprecated compatibility field from older libp2p-mesh versions. Use relayList for relay nodes.",
|
|
108
|
+
},
|
|
109
|
+
relayAccountId: {
|
|
110
|
+
type: "string",
|
|
111
|
+
deprecated: true,
|
|
112
|
+
description: "Deprecated compatibility field from older libp2p-mesh versions. This value is ignored.",
|
|
113
|
+
},
|
|
104
114
|
discoverRelays: {
|
|
105
115
|
type: "number",
|
|
106
116
|
default: 0,
|
package/openclaw.plugin.json
CHANGED
|
@@ -4,6 +4,17 @@
|
|
|
4
4
|
"onStartup": true
|
|
5
5
|
},
|
|
6
6
|
"channels": ["libp2p-mesh"],
|
|
7
|
+
"channelConfigs": {
|
|
8
|
+
"libp2p-mesh": {
|
|
9
|
+
"label": "P2P Mesh",
|
|
10
|
+
"description": "libp2p mesh network channel.",
|
|
11
|
+
"schema": {
|
|
12
|
+
"type": "object",
|
|
13
|
+
"additionalProperties": false,
|
|
14
|
+
"properties": {}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
},
|
|
7
18
|
"enabledByDefault": true,
|
|
8
19
|
"name": "libp2p Mesh Network",
|
|
9
20
|
"description": "P2P network for cross-instance agent communication via libp2p.",
|
|
@@ -91,6 +102,16 @@
|
|
|
91
102
|
"items": { "type": "string" },
|
|
92
103
|
"description": "Multiaddrs of relays to reserve a slot on (each entry must end in /p2p/<peer-id>)."
|
|
93
104
|
},
|
|
105
|
+
"relayChannel": {
|
|
106
|
+
"type": "string",
|
|
107
|
+
"deprecated": true,
|
|
108
|
+
"description": "Deprecated compatibility field from older libp2p-mesh versions. Use relayList for relay nodes."
|
|
109
|
+
},
|
|
110
|
+
"relayAccountId": {
|
|
111
|
+
"type": "string",
|
|
112
|
+
"deprecated": true,
|
|
113
|
+
"description": "Deprecated compatibility field from older libp2p-mesh versions. This value is ignored."
|
|
114
|
+
},
|
|
94
115
|
"discoverRelays": {
|
|
95
116
|
"type": "number",
|
|
96
117
|
"default": 0,
|
package/package.json
CHANGED
package/src/inbound-delivery.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type {
|
|
2
|
+
ChannelOutboundAdapter,
|
|
3
|
+
OpenClawConfig,
|
|
4
|
+
} from "openclaw/plugin-sdk/core";
|
|
2
5
|
import type {
|
|
3
6
|
InboundDeliveryAdapter,
|
|
4
7
|
InboundDeliveryRequest,
|
|
@@ -11,107 +14,60 @@ export type DeliveryLogger = {
|
|
|
11
14
|
warn?: (message: string) => void;
|
|
12
15
|
};
|
|
13
16
|
|
|
14
|
-
export
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
export type LoadChannelOutboundAdapter = (
|
|
18
|
+
channel: string,
|
|
19
|
+
) => Promise<ChannelOutboundAdapter | undefined>;
|
|
20
|
+
|
|
21
|
+
function summarizeError(error: unknown): string {
|
|
22
|
+
return error instanceof Error ? error.message : String(error);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function createOpenClawRuntimeInboundDelivery(options: {
|
|
26
|
+
config: OpenClawConfig;
|
|
27
|
+
loadAdapter: LoadChannelOutboundAdapter;
|
|
17
28
|
logger?: DeliveryLogger;
|
|
18
29
|
}): InboundDeliveryAdapter {
|
|
19
|
-
const
|
|
20
|
-
const timeoutMs = options?.timeoutMs ?? 15000;
|
|
21
|
-
const logger = options?.logger;
|
|
30
|
+
const { config, loadAdapter, logger } = options;
|
|
22
31
|
|
|
23
32
|
return {
|
|
24
|
-
deliver(request: InboundDeliveryRequest): Promise<InboundDeliveryResult> {
|
|
25
|
-
const args = [
|
|
26
|
-
"message",
|
|
27
|
-
"send",
|
|
28
|
-
"--channel",
|
|
29
|
-
request.channel,
|
|
30
|
-
"--target",
|
|
31
|
-
request.target,
|
|
32
|
-
"--message",
|
|
33
|
-
request.text,
|
|
34
|
-
];
|
|
35
|
-
|
|
33
|
+
async deliver(request: InboundDeliveryRequest): Promise<InboundDeliveryResult> {
|
|
36
34
|
logger?.debug?.(
|
|
37
|
-
`[libp2p-mesh] Forwarding inbound delivery via
|
|
35
|
+
`[libp2p-mesh] Forwarding inbound delivery via runtime channel adapter: ${request.channel}/${request.target}`,
|
|
38
36
|
);
|
|
39
37
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const finish = (result: InboundDeliveryResult): void => {
|
|
48
|
-
if (settled) {
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
settled = true;
|
|
52
|
-
if (timeout) {
|
|
53
|
-
clearTimeout(timeout);
|
|
54
|
-
}
|
|
55
|
-
resolve(result);
|
|
38
|
+
const adapter = await loadAdapter(request.channel);
|
|
39
|
+
if (!adapter?.sendText) {
|
|
40
|
+
return {
|
|
41
|
+
ok: false,
|
|
42
|
+
channel: request.channel,
|
|
43
|
+
target: request.target,
|
|
44
|
+
error: `channel ${request.channel} does not expose runtime text delivery`,
|
|
56
45
|
};
|
|
46
|
+
}
|
|
57
47
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
finish({
|
|
64
|
-
ok: false,
|
|
65
|
-
channel: request.channel,
|
|
66
|
-
target: request.target,
|
|
67
|
-
error: `openclaw message send timed out after ${timeoutMs}ms`,
|
|
68
|
-
});
|
|
69
|
-
}, timeoutMs);
|
|
70
|
-
|
|
71
|
-
child.stdout.on("data", (chunk: Buffer) => {
|
|
72
|
-
stdout.push(chunk);
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
child.stderr.on("data", (chunk: Buffer) => {
|
|
76
|
-
stderr.push(chunk);
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
child.on("error", (err) => {
|
|
80
|
-
finish({
|
|
81
|
-
ok: false,
|
|
82
|
-
channel: request.channel,
|
|
83
|
-
target: request.target,
|
|
84
|
-
error: String(err),
|
|
85
|
-
});
|
|
48
|
+
try {
|
|
49
|
+
await adapter.sendText({
|
|
50
|
+
cfg: config,
|
|
51
|
+
to: request.target,
|
|
52
|
+
text: request.text,
|
|
86
53
|
});
|
|
54
|
+
} catch (error) {
|
|
55
|
+
return {
|
|
56
|
+
ok: false,
|
|
57
|
+
channel: request.channel,
|
|
58
|
+
target: request.target,
|
|
59
|
+
error: summarizeError(error),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
87
62
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
target: request.target,
|
|
97
|
-
});
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const stderrText = Buffer.concat(stderr).toString().trim();
|
|
102
|
-
const stdoutText = Buffer.concat(stdout).toString().trim();
|
|
103
|
-
|
|
104
|
-
finish({
|
|
105
|
-
ok: false,
|
|
106
|
-
channel: request.channel,
|
|
107
|
-
target: request.target,
|
|
108
|
-
error:
|
|
109
|
-
stderrText ||
|
|
110
|
-
stdoutText ||
|
|
111
|
-
`openclaw message send exited with code ${code}`,
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
});
|
|
63
|
+
logger?.info?.(
|
|
64
|
+
`[libp2p-mesh] Delivered inbound message to ${request.channel}/${request.target}`,
|
|
65
|
+
);
|
|
66
|
+
return {
|
|
67
|
+
ok: true,
|
|
68
|
+
channel: request.channel,
|
|
69
|
+
target: request.target,
|
|
70
|
+
};
|
|
115
71
|
},
|
|
116
72
|
};
|
|
117
73
|
}
|
package/src/plugin.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/core";
|
|
2
2
|
import { createLibp2pMeshChannel } from "./channel.js";
|
|
3
3
|
import { handleP2PInbound } from "./inbound.js";
|
|
4
|
-
import {
|
|
4
|
+
import { createOpenClawRuntimeInboundDelivery } from "./inbound-delivery.js";
|
|
5
5
|
import { createInstancePeerStore } from "./instance-peer-store.js";
|
|
6
6
|
import { createInstanceRouter } from "./instance-router.js";
|
|
7
7
|
import { createMeshNetwork } from "./mesh.js";
|
|
@@ -18,7 +18,11 @@ export function registerLibp2pMesh(api: OpenClawPluginApi) {
|
|
|
18
18
|
logger: api.logger,
|
|
19
19
|
});
|
|
20
20
|
const store = createInstancePeerStore({ logger: api.logger });
|
|
21
|
-
const delivery =
|
|
21
|
+
const delivery = createOpenClawRuntimeInboundDelivery({
|
|
22
|
+
config: api.config,
|
|
23
|
+
loadAdapter: api.runtime.channel.outbound.loadAdapter,
|
|
24
|
+
logger: api.logger,
|
|
25
|
+
});
|
|
22
26
|
const router = createInstanceRouter({
|
|
23
27
|
mesh,
|
|
24
28
|
store,
|
package/src/types.ts
CHANGED
|
@@ -187,6 +187,13 @@ export interface MeshConfig {
|
|
|
187
187
|
* reservation open with each one so other peers can dial us through them.
|
|
188
188
|
*/
|
|
189
189
|
relayList?: string[];
|
|
190
|
+
/**
|
|
191
|
+
* Deprecated pre-2026.6 config keys kept so existing OpenClaw configs keep
|
|
192
|
+
* validating after upgrade. Relay selection is now configured with
|
|
193
|
+
* `relayList`; inbound display uses `inboundChannel`/`inboundTarget`.
|
|
194
|
+
*/
|
|
195
|
+
relayChannel?: string;
|
|
196
|
+
relayAccountId?: string;
|
|
190
197
|
/**
|
|
191
198
|
* Number of relays to auto-discover via content routing. Requires DHT.
|
|
192
199
|
* Default `0` (disabled). Set to e.g. `2` to look up public relays.
|