@phronesis-io/openclaw-eigenflux 0.0.4 → 0.0.7
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 -161
- package/dist/agent-prompt-templates.d.ts +14 -12
- package/dist/agent-prompt-templates.d.ts.map +1 -1
- package/dist/agent-prompt-templates.js +27 -35
- package/dist/agent-prompt-templates.js.map +1 -1
- package/dist/cli-executor.d.ts +32 -0
- package/dist/cli-executor.d.ts.map +1 -0
- package/dist/cli-executor.js +75 -0
- package/dist/cli-executor.js.map +1 -0
- package/dist/config.d.ts +41 -126
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +94 -229
- package/dist/config.js.map +1 -1
- package/dist/credentials-loader.d.ts +6 -5
- package/dist/credentials-loader.d.ts.map +1 -1
- package/dist/credentials-loader.js +17 -21
- package/dist/credentials-loader.js.map +1 -1
- package/dist/index.d.ts +3 -73
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +262 -275
- package/dist/index.js.map +1 -1
- package/dist/notification-route-resolver.d.ts +24 -2
- package/dist/notification-route-resolver.d.ts.map +1 -1
- package/dist/notification-route-resolver.js +258 -43
- package/dist/notification-route-resolver.js.map +1 -1
- package/dist/notifier.d.ts +9 -17
- package/dist/notifier.d.ts.map +1 -1
- package/dist/notifier.js +133 -66
- package/dist/notifier.js.map +1 -1
- package/dist/polling-client.d.ts +31 -19
- package/dist/polling-client.d.ts.map +1 -1
- package/dist/polling-client.js +102 -127
- package/dist/polling-client.js.map +1 -1
- package/dist/reply-target.d.ts +8 -0
- package/dist/reply-target.d.ts.map +1 -0
- package/dist/reply-target.js +104 -0
- package/dist/reply-target.js.map +1 -0
- package/dist/session-route-memory.d.ts +12 -3
- package/dist/session-route-memory.d.ts.map +1 -1
- package/dist/session-route-memory.js +83 -80
- package/dist/session-route-memory.js.map +1 -1
- package/dist/stream-client.d.ts +48 -0
- package/dist/stream-client.d.ts.map +1 -0
- package/dist/stream-client.js +168 -0
- package/dist/stream-client.js.map +1 -0
- package/openclaw.plugin.json +5 -75
- package/package.json +6 -8
- package/skills/ef-broadcast/SKILL.md +84 -0
- package/skills/ef-broadcast/references/feed.md +127 -0
- package/skills/ef-broadcast/references/publish.md +119 -0
- package/skills/ef-communication/SKILL.md +95 -0
- package/skills/ef-communication/references/message.md +132 -0
- package/skills/ef-communication/references/relations.md +215 -0
- package/skills/ef-communication/references/stream.md +66 -0
- package/skills/ef-profile/SKILL.md +138 -0
- package/skills/ef-profile/references/auth.md +103 -0
- package/skills/ef-profile/references/config.md +54 -0
- package/skills/ef-profile/references/onboarding.md +172 -0
- package/skills/ef-profile/references/server-management.md +67 -0
- package/dist/gateway-rpc-client.d.ts +0 -26
- package/dist/gateway-rpc-client.d.ts.map +0 -1
- package/dist/gateway-rpc-client.js +0 -288
- package/dist/gateway-rpc-client.js.map +0 -1
- package/dist/pm-polling-client.d.ts +0 -52
- package/dist/pm-polling-client.d.ts.map +0 -1
- package/dist/pm-polling-client.js +0 -182
- package/dist/pm-polling-client.js.map +0 -1
package/dist/config.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Configuration for the EigenFlux plugin.
|
|
3
|
+
*
|
|
4
|
+
* Server management is now handled by the eigenflux CLI.
|
|
5
|
+
* The plugin config only holds plugin-level settings and
|
|
6
|
+
* per-server notification routing overrides.
|
|
3
7
|
*/
|
|
4
8
|
import { Logger } from './logger';
|
|
5
9
|
export type NotificationRouteOverrides = {
|
|
@@ -9,32 +13,7 @@ export type NotificationRouteOverrides = {
|
|
|
9
13
|
replyTo: boolean;
|
|
10
14
|
replyAccountId: boolean;
|
|
11
15
|
};
|
|
12
|
-
export type
|
|
13
|
-
enabled?: boolean;
|
|
14
|
-
name?: string;
|
|
15
|
-
endpoint?: string;
|
|
16
|
-
workdir?: string;
|
|
17
|
-
pollInterval?: number;
|
|
18
|
-
pmPollInterval?: number;
|
|
19
|
-
sessionKey?: string;
|
|
20
|
-
agentId?: string;
|
|
21
|
-
replyChannel?: string;
|
|
22
|
-
replyTo?: string;
|
|
23
|
-
replyAccountId?: string;
|
|
24
|
-
};
|
|
25
|
-
export type EigenFluxPluginConfig = {
|
|
26
|
-
gatewayUrl?: string;
|
|
27
|
-
gatewayToken?: string;
|
|
28
|
-
openclawCliBin?: string;
|
|
29
|
-
servers?: EigenFluxServerConfig[];
|
|
30
|
-
};
|
|
31
|
-
export type ResolvedEigenFluxServerConfig = {
|
|
32
|
-
enabled: boolean;
|
|
33
|
-
name: string;
|
|
34
|
-
endpoint: string;
|
|
35
|
-
workdir: string;
|
|
36
|
-
pollIntervalSec: number;
|
|
37
|
-
pmPollIntervalSec: number;
|
|
16
|
+
export type RoutingConfig = {
|
|
38
17
|
sessionKey: string;
|
|
39
18
|
agentId: string;
|
|
40
19
|
replyChannel?: string;
|
|
@@ -42,127 +21,63 @@ export type ResolvedEigenFluxServerConfig = {
|
|
|
42
21
|
replyAccountId?: string;
|
|
43
22
|
routeOverrides: NotificationRouteOverrides;
|
|
44
23
|
};
|
|
24
|
+
export type DiscoveredServer = {
|
|
25
|
+
name: string;
|
|
26
|
+
endpoint: string;
|
|
27
|
+
stream_endpoint?: string;
|
|
28
|
+
current: boolean;
|
|
29
|
+
};
|
|
30
|
+
export type EigenFluxPluginConfig = {
|
|
31
|
+
eigenfluxBin?: string;
|
|
32
|
+
skills?: string[];
|
|
33
|
+
openclawCliBin?: string;
|
|
34
|
+
serverRouting?: Record<string, {
|
|
35
|
+
sessionKey?: string;
|
|
36
|
+
agentId?: string;
|
|
37
|
+
replyChannel?: string;
|
|
38
|
+
replyTo?: string;
|
|
39
|
+
replyAccountId?: string;
|
|
40
|
+
}>;
|
|
41
|
+
};
|
|
45
42
|
export type ResolvedEigenFluxPluginConfig = {
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
eigenfluxBin: string;
|
|
44
|
+
skills: string[];
|
|
48
45
|
openclawCliBin: string;
|
|
49
|
-
|
|
46
|
+
serverRouting: Record<string, RoutingConfig>;
|
|
50
47
|
};
|
|
51
|
-
type
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
48
|
+
export type DiscoveryResult = {
|
|
49
|
+
kind: 'ok';
|
|
50
|
+
servers: DiscoveredServer[];
|
|
51
|
+
} | {
|
|
52
|
+
kind: 'not_installed';
|
|
53
|
+
bin: string;
|
|
57
54
|
};
|
|
55
|
+
export declare function discoverServers(eigenfluxBin: string, logger?: Logger): Promise<DiscoveryResult>;
|
|
56
|
+
export declare function resolveEigenfluxHome(): string;
|
|
57
|
+
export declare function resolvePluginConfig(pluginConfig: unknown, logger?: Logger): ResolvedEigenFluxPluginConfig;
|
|
58
58
|
export declare function expandHomeDir(input: string): string;
|
|
59
|
-
export declare function resolveServerSkillPath(server: {
|
|
60
|
-
endpoint: string;
|
|
61
|
-
workdir: string;
|
|
62
|
-
}): string;
|
|
63
|
-
export declare function resolvePluginConfig(pluginConfig: unknown, globalConfig?: GlobalGatewayConfig, logger?: Logger): ResolvedEigenFluxPluginConfig;
|
|
64
59
|
export declare const PLUGIN_CONFIG: {
|
|
65
|
-
readonly
|
|
66
|
-
readonly DEFAULT_ENDPOINT: "https://www.eigenflux.ai";
|
|
67
|
-
readonly DEFAULT_GATEWAY_URL: "ws://127.0.0.1:18789";
|
|
60
|
+
readonly DEFAULT_EIGENFLUX_BIN: "eigenflux";
|
|
68
61
|
readonly DEFAULT_SESSION_KEY: "main";
|
|
69
62
|
readonly DEFAULT_AGENT_ID: "main";
|
|
70
63
|
readonly DEFAULT_OPENCLAW_CLI_BIN: "openclaw";
|
|
71
|
-
readonly DEFAULT_POLL_INTERVAL_SEC: 300;
|
|
72
|
-
readonly DEFAULT_PM_POLL_INTERVAL_SEC: 60;
|
|
73
|
-
readonly MIN_POLL_INTERVAL_SEC: 10;
|
|
74
|
-
readonly MAX_POLL_INTERVAL_SEC: number;
|
|
75
64
|
readonly HOST_KIND: "openclaw";
|
|
76
|
-
readonly
|
|
77
|
-
readonly PLUGIN_VERSION: "0.0.4";
|
|
78
|
-
readonly USER_AGENT: string;
|
|
65
|
+
readonly PLUGIN_VERSION: "0.0.7";
|
|
79
66
|
};
|
|
80
|
-
export declare function buildEigenFluxRequestHeaders(accessToken: string): Record<string, string>;
|
|
81
67
|
export declare const PLUGIN_CONFIG_SCHEMA: {
|
|
82
68
|
readonly type: "object";
|
|
83
69
|
readonly additionalProperties: false;
|
|
84
70
|
readonly properties: {
|
|
85
|
-
readonly
|
|
71
|
+
readonly eigenfluxBin: {
|
|
86
72
|
readonly type: "string";
|
|
87
|
-
readonly description: "
|
|
88
|
-
readonly default: "
|
|
89
|
-
};
|
|
90
|
-
readonly gatewayToken: {
|
|
91
|
-
readonly type: "string";
|
|
92
|
-
readonly description: "Optional gateway token override used for Gateway RPC fallback";
|
|
73
|
+
readonly description: "Path to the eigenflux CLI binary";
|
|
74
|
+
readonly default: "eigenflux";
|
|
93
75
|
};
|
|
94
76
|
readonly openclawCliBin: {
|
|
95
77
|
readonly type: "string";
|
|
96
78
|
readonly description: "OpenClaw CLI binary used by runtime command fallbacks";
|
|
97
79
|
readonly default: "openclaw";
|
|
98
80
|
};
|
|
99
|
-
readonly servers: {
|
|
100
|
-
readonly type: "array";
|
|
101
|
-
readonly description: "Server list. When empty or when no server named eigenflux is provided, the plugin prepends a default eigenflux server.";
|
|
102
|
-
readonly default: readonly [];
|
|
103
|
-
readonly items: {
|
|
104
|
-
readonly type: "object";
|
|
105
|
-
readonly additionalProperties: false;
|
|
106
|
-
readonly properties: {
|
|
107
|
-
readonly enabled: {
|
|
108
|
-
readonly type: "boolean";
|
|
109
|
-
readonly description: "Enable or disable background polling for this server";
|
|
110
|
-
readonly default: true;
|
|
111
|
-
};
|
|
112
|
-
readonly name: {
|
|
113
|
-
readonly type: "string";
|
|
114
|
-
readonly description: "Server name used for routing, workdir defaults, and diagnostics";
|
|
115
|
-
readonly default: "eigenflux";
|
|
116
|
-
};
|
|
117
|
-
readonly endpoint: {
|
|
118
|
-
readonly type: "string";
|
|
119
|
-
readonly description: "EigenFlux API base URL for this server";
|
|
120
|
-
readonly default: "https://www.eigenflux.ai";
|
|
121
|
-
};
|
|
122
|
-
readonly workdir: {
|
|
123
|
-
readonly type: "string";
|
|
124
|
-
readonly description: "Directory used to store server credentials and remembered session state";
|
|
125
|
-
};
|
|
126
|
-
readonly pollInterval: {
|
|
127
|
-
readonly type: "integer";
|
|
128
|
-
readonly minimum: 10;
|
|
129
|
-
readonly maximum: number;
|
|
130
|
-
readonly description: "Feed polling interval in seconds for this server";
|
|
131
|
-
readonly default: 300;
|
|
132
|
-
};
|
|
133
|
-
readonly pmPollInterval: {
|
|
134
|
-
readonly type: "integer";
|
|
135
|
-
readonly minimum: 10;
|
|
136
|
-
readonly maximum: number;
|
|
137
|
-
readonly description: "Private message polling interval in seconds for this server";
|
|
138
|
-
readonly default: 60;
|
|
139
|
-
};
|
|
140
|
-
readonly sessionKey: {
|
|
141
|
-
readonly type: "string";
|
|
142
|
-
readonly description: "Target session key used by runtime.subagent and heartbeat fallback";
|
|
143
|
-
readonly default: "main";
|
|
144
|
-
};
|
|
145
|
-
readonly agentId: {
|
|
146
|
-
readonly type: "string";
|
|
147
|
-
readonly description: "Agent id used by Gateway agent and CLI fallbacks";
|
|
148
|
-
readonly default: "main";
|
|
149
|
-
};
|
|
150
|
-
readonly replyChannel: {
|
|
151
|
-
readonly type: "string";
|
|
152
|
-
readonly description: "Explicit reply channel used by Gateway agent and CLI fallbacks";
|
|
153
|
-
};
|
|
154
|
-
readonly replyTo: {
|
|
155
|
-
readonly type: "string";
|
|
156
|
-
readonly description: "Explicit reply target used by Gateway agent and CLI fallbacks";
|
|
157
|
-
};
|
|
158
|
-
readonly replyAccountId: {
|
|
159
|
-
readonly type: "string";
|
|
160
|
-
readonly description: "Optional reply account id for multi-account channel delivery";
|
|
161
|
-
};
|
|
162
|
-
};
|
|
163
|
-
};
|
|
164
|
-
};
|
|
165
81
|
};
|
|
166
82
|
};
|
|
167
|
-
export {};
|
|
168
83
|
//# sourceMappingURL=config.d.ts.map
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAalC,MAAM,MAAM,0BAA0B,GAAG;IACvC,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,0BAA0B,CAAC;CAC5C,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC,CAAC;CACJ,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CAC9C,CAAC;AA8FF,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,gBAAgB,EAAE,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3C,wBAAsB,eAAe,CACnC,YAAY,EAAE,MAAM,EACpB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,eAAe,CAAC,CA0B1B;AAID,wBAAgB,oBAAoB,IAAI,MAAM,CAU7C;AA6BD,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,OAAO,EACrB,MAAM,CAAC,EAAE,MAAM,GACd,6BAA6B,CAuB/B;AAID,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQnD;AAED,eAAO,MAAM,aAAa;;;;;;;CAOhB,CAAC;AAEX,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;CAevB,CAAC"}
|
package/dist/config.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Configuration for the EigenFlux plugin.
|
|
4
|
+
*
|
|
5
|
+
* Server management is now handled by the eigenflux CLI.
|
|
6
|
+
* The plugin config only holds plugin-level settings and
|
|
7
|
+
* per-server notification routing overrides.
|
|
4
8
|
*/
|
|
5
9
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
@@ -37,45 +41,21 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
37
41
|
})();
|
|
38
42
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
43
|
exports.PLUGIN_CONFIG_SCHEMA = exports.PLUGIN_CONFIG = void 0;
|
|
40
|
-
exports.
|
|
41
|
-
exports.
|
|
44
|
+
exports.discoverServers = discoverServers;
|
|
45
|
+
exports.resolveEigenfluxHome = resolveEigenfluxHome;
|
|
42
46
|
exports.resolvePluginConfig = resolvePluginConfig;
|
|
43
|
-
exports.
|
|
44
|
-
const fs = __importStar(require("fs"));
|
|
47
|
+
exports.expandHomeDir = expandHomeDir;
|
|
45
48
|
const os = __importStar(require("os"));
|
|
46
49
|
const path = __importStar(require("path"));
|
|
47
|
-
const
|
|
48
|
-
const
|
|
49
|
-
const
|
|
50
|
-
const
|
|
50
|
+
const reply_target_1 = require("./reply-target");
|
|
51
|
+
const cli_executor_1 = require("./cli-executor");
|
|
52
|
+
const PLUGIN_VERSION = '0.0.7';
|
|
53
|
+
const DEFAULT_EIGENFLUX_BIN = 'eigenflux';
|
|
51
54
|
const DEFAULT_SESSION_KEY = 'main';
|
|
52
55
|
const DEFAULT_AGENT_ID = 'main';
|
|
53
56
|
const DEFAULT_OPENCLAW_CLI_BIN = 'openclaw';
|
|
54
|
-
const DEFAULT_POLL_INTERVAL_SEC = 300;
|
|
55
|
-
const DEFAULT_PM_POLL_INTERVAL_SEC = 60;
|
|
56
|
-
const MIN_POLL_INTERVAL_SEC = 10;
|
|
57
|
-
const MAX_POLL_INTERVAL_SEC = 24 * 60 * 60;
|
|
58
57
|
const HOST_KIND = 'openclaw';
|
|
59
|
-
|
|
60
|
-
try {
|
|
61
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
62
|
-
const pkg = require('openclaw/package.json');
|
|
63
|
-
return pkg.version;
|
|
64
|
-
}
|
|
65
|
-
catch {
|
|
66
|
-
return undefined;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
function buildUserAgent() {
|
|
70
|
-
const parts = [];
|
|
71
|
-
parts.push(`node/${process.version.replace(/^v/, '')}`);
|
|
72
|
-
parts.push(`(${os.platform()}; ${os.arch()}; ${os.release()})`);
|
|
73
|
-
const openclawVersion = detectOpenClawVersion();
|
|
74
|
-
if (openclawVersion) {
|
|
75
|
-
parts.push(`openclaw/${openclawVersion}`);
|
|
76
|
-
}
|
|
77
|
-
return parts.join(' ');
|
|
78
|
-
}
|
|
58
|
+
// ─── Helpers ────────────────────────────────────────────────────────────────
|
|
79
59
|
function isRecord(value) {
|
|
80
60
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
81
61
|
}
|
|
@@ -86,30 +66,6 @@ function readNonEmptyString(value) {
|
|
|
86
66
|
const trimmed = value.trim();
|
|
87
67
|
return trimmed.length > 0 ? trimmed : undefined;
|
|
88
68
|
}
|
|
89
|
-
function parsePositiveInteger(value, fallback) {
|
|
90
|
-
if (typeof value === 'number' && Number.isFinite(value) && value > 0) {
|
|
91
|
-
return Math.floor(value);
|
|
92
|
-
}
|
|
93
|
-
if (typeof value === 'string') {
|
|
94
|
-
const parsed = parseInt(value, 10);
|
|
95
|
-
if (Number.isFinite(parsed) && parsed > 0) {
|
|
96
|
-
return parsed;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
return fallback;
|
|
100
|
-
}
|
|
101
|
-
function parsePollingIntervalSeconds(value, fallback, options) {
|
|
102
|
-
const parsed = parsePositiveInteger(value, fallback);
|
|
103
|
-
if (parsed < MIN_POLL_INTERVAL_SEC) {
|
|
104
|
-
options.logger?.warn(`${options.fieldName} for server "${options.serverName}" is below ${MIN_POLL_INTERVAL_SEC}s; clamping to ${MIN_POLL_INTERVAL_SEC}s`);
|
|
105
|
-
return MIN_POLL_INTERVAL_SEC;
|
|
106
|
-
}
|
|
107
|
-
if (parsed <= MAX_POLL_INTERVAL_SEC) {
|
|
108
|
-
return parsed;
|
|
109
|
-
}
|
|
110
|
-
options.logger?.warn(`${options.fieldName} for server "${options.serverName}" exceeds ${MAX_POLL_INTERVAL_SEC}s; clamping to ${MAX_POLL_INTERVAL_SEC}s`);
|
|
111
|
-
return MAX_POLL_INTERVAL_SEC;
|
|
112
|
-
}
|
|
113
69
|
function isSessionPeerShape(value) {
|
|
114
70
|
const normalized = value?.trim().toLowerCase();
|
|
115
71
|
return (normalized === 'direct' ||
|
|
@@ -132,85 +88,108 @@ function deriveNotificationRoute(sessionKey) {
|
|
|
132
88
|
agentId,
|
|
133
89
|
replyChannel: readNonEmptyString(parts[2]),
|
|
134
90
|
replyAccountId: readNonEmptyString(parts[3]),
|
|
135
|
-
replyTo:
|
|
91
|
+
replyTo: (0, reply_target_1.normalizeReplyTarget)(parts.slice(5).join(':'), {
|
|
92
|
+
channel: readNonEmptyString(parts[2]),
|
|
93
|
+
sessionKey: trimmed,
|
|
94
|
+
}),
|
|
136
95
|
};
|
|
137
96
|
}
|
|
138
97
|
if (parts.length >= 5 && isSessionPeerShape(parts[3])) {
|
|
139
98
|
return {
|
|
140
99
|
agentId,
|
|
141
100
|
replyChannel: readNonEmptyString(parts[2]),
|
|
142
|
-
replyTo:
|
|
101
|
+
replyTo: (0, reply_target_1.normalizeReplyTarget)(parts.slice(4).join(':'), {
|
|
102
|
+
channel: readNonEmptyString(parts[2]),
|
|
103
|
+
sessionKey: trimmed,
|
|
104
|
+
}),
|
|
143
105
|
};
|
|
144
106
|
}
|
|
145
107
|
return { agentId };
|
|
146
108
|
}
|
|
147
109
|
function createRouteOverrides(normalized) {
|
|
110
|
+
const sessionKey = readNonEmptyString(normalized.sessionKey);
|
|
111
|
+
const agentId = readNonEmptyString(normalized.agentId);
|
|
112
|
+
const replyChannel = readNonEmptyString(normalized.replyChannel);
|
|
113
|
+
const replyTo = readNonEmptyString(normalized.replyTo);
|
|
114
|
+
const replyAccountId = readNonEmptyString(normalized.replyAccountId);
|
|
148
115
|
return {
|
|
149
|
-
sessionKey:
|
|
150
|
-
agentId:
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
116
|
+
sessionKey: sessionKey !== undefined && sessionKey !== DEFAULT_SESSION_KEY,
|
|
117
|
+
agentId: agentId !== undefined &&
|
|
118
|
+
agentId !== DEFAULT_AGENT_ID &&
|
|
119
|
+
!(sessionKey && deriveNotificationRoute(sessionKey).agentId === agentId),
|
|
120
|
+
replyChannel: replyChannel !== undefined,
|
|
121
|
+
replyTo: replyTo !== undefined,
|
|
122
|
+
replyAccountId: replyAccountId !== undefined,
|
|
154
123
|
};
|
|
155
124
|
}
|
|
156
|
-
function
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
125
|
+
async function discoverServers(eigenfluxBin, logger) {
|
|
126
|
+
const result = await (0, cli_executor_1.execEigenflux)(eigenfluxBin, ['server', 'list', '--format', 'json'], { logger });
|
|
127
|
+
if (result.kind === 'success') {
|
|
128
|
+
if (Array.isArray(result.data)) {
|
|
129
|
+
return { kind: 'ok', servers: result.data };
|
|
130
|
+
}
|
|
131
|
+
logger?.warn('eigenflux server list returned non-array data');
|
|
132
|
+
return { kind: 'ok', servers: [] };
|
|
133
|
+
}
|
|
134
|
+
if (result.kind === 'not_installed') {
|
|
135
|
+
return { kind: 'not_installed', bin: result.bin };
|
|
136
|
+
}
|
|
137
|
+
if (result.kind === 'auth_required') {
|
|
138
|
+
logger?.warn('eigenflux server list: auth required (unexpected)');
|
|
139
|
+
return { kind: 'ok', servers: [] };
|
|
140
|
+
}
|
|
141
|
+
logger?.error(`eigenflux server list failed: ${result.error.message}`);
|
|
142
|
+
return { kind: 'ok', servers: [] };
|
|
143
|
+
}
|
|
144
|
+
// ─── EigenFlux Home ─────────────────────────────────────────────────────────
|
|
145
|
+
function resolveEigenfluxHome() {
|
|
146
|
+
const envHome = process.env.EIGENFLUX_HOME;
|
|
147
|
+
if (envHome) {
|
|
148
|
+
const expanded = expandHomeDir(envHome);
|
|
149
|
+
if (!expanded.endsWith('.eigenflux')) {
|
|
150
|
+
return path.join(expanded, '.eigenflux');
|
|
151
|
+
}
|
|
152
|
+
return expanded;
|
|
176
153
|
}
|
|
177
|
-
|
|
178
|
-
usedNames.add(uniqueName);
|
|
179
|
-
return uniqueName;
|
|
154
|
+
return path.join(os.homedir(), '.eigenflux');
|
|
180
155
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
const
|
|
184
|
-
(index === 0 ? DEFAULT_SERVER_NAME : `server-${index + 1}`);
|
|
185
|
-
const name = createServerName(rawName, usedNames);
|
|
156
|
+
// ─── Config Resolution ──────────────────────────────────────────────────────
|
|
157
|
+
function resolveRoutingConfig(raw, logger) {
|
|
158
|
+
const normalized = isRecord(raw) ? raw : {};
|
|
186
159
|
const sessionKey = readNonEmptyString(normalized.sessionKey) ?? DEFAULT_SESSION_KEY;
|
|
187
160
|
const derivedRoute = deriveNotificationRoute(sessionKey);
|
|
188
|
-
const
|
|
189
|
-
const
|
|
161
|
+
const replyChannel = readNonEmptyString(normalized.replyChannel) ?? derivedRoute.replyChannel;
|
|
162
|
+
const replyTo = (0, reply_target_1.normalizeReplyTarget)(readNonEmptyString(normalized.replyTo), {
|
|
163
|
+
channel: replyChannel,
|
|
164
|
+
sessionKey,
|
|
165
|
+
}) ?? derivedRoute.replyTo;
|
|
190
166
|
return {
|
|
191
|
-
enabled: normalized.enabled !== false,
|
|
192
|
-
name,
|
|
193
|
-
endpoint: readNonEmptyString(normalized.endpoint) ?? DEFAULT_ENDPOINT,
|
|
194
|
-
workdir,
|
|
195
|
-
pollIntervalSec: parsePollingIntervalSeconds(normalized.pollInterval, DEFAULT_POLL_INTERVAL_SEC, {
|
|
196
|
-
fieldName: 'pollInterval',
|
|
197
|
-
serverName: name,
|
|
198
|
-
logger,
|
|
199
|
-
}),
|
|
200
|
-
pmPollIntervalSec: parsePollingIntervalSeconds(normalized.pmPollInterval, DEFAULT_PM_POLL_INTERVAL_SEC, {
|
|
201
|
-
fieldName: 'pmPollInterval',
|
|
202
|
-
serverName: name,
|
|
203
|
-
logger,
|
|
204
|
-
}),
|
|
205
167
|
sessionKey,
|
|
206
168
|
agentId: readNonEmptyString(normalized.agentId) ?? derivedRoute.agentId ?? DEFAULT_AGENT_ID,
|
|
207
|
-
replyChannel
|
|
208
|
-
replyTo
|
|
169
|
+
replyChannel,
|
|
170
|
+
replyTo,
|
|
209
171
|
replyAccountId: readNonEmptyString(normalized.replyAccountId) ?? derivedRoute.replyAccountId,
|
|
210
172
|
routeOverrides: createRouteOverrides(normalized),
|
|
211
|
-
...(sessionStorePath ? { sessionStorePath: expandHomeDir(sessionStorePath) } : {}),
|
|
212
173
|
};
|
|
213
174
|
}
|
|
175
|
+
function resolvePluginConfig(pluginConfig, logger) {
|
|
176
|
+
const normalized = isRecord(pluginConfig) ? pluginConfig : {};
|
|
177
|
+
const rawRouting = isRecord(normalized.serverRouting) ? normalized.serverRouting : {};
|
|
178
|
+
const serverRouting = {};
|
|
179
|
+
for (const [serverName, rawConfig] of Object.entries(rawRouting)) {
|
|
180
|
+
serverRouting[serverName] = resolveRoutingConfig(isRecord(rawConfig) ? rawConfig : undefined, logger);
|
|
181
|
+
}
|
|
182
|
+
const rawSkills = Array.isArray(normalized.skills)
|
|
183
|
+
? normalized.skills.filter((s) => typeof s === 'string' && s.trim().length > 0)
|
|
184
|
+
: ['ef-broadcast', 'ef-communication'];
|
|
185
|
+
return {
|
|
186
|
+
eigenfluxBin: readNonEmptyString(normalized.eigenfluxBin) ?? DEFAULT_EIGENFLUX_BIN,
|
|
187
|
+
skills: rawSkills,
|
|
188
|
+
openclawCliBin: readNonEmptyString(normalized.openclawCliBin) ?? DEFAULT_OPENCLAW_CLI_BIN,
|
|
189
|
+
serverRouting,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
// ─── Exports ────────────────────────────────────────────────────────────────
|
|
214
193
|
function expandHomeDir(input) {
|
|
215
194
|
if (input === '~') {
|
|
216
195
|
return os.homedir();
|
|
@@ -220,142 +199,28 @@ function expandHomeDir(input) {
|
|
|
220
199
|
}
|
|
221
200
|
return input;
|
|
222
201
|
}
|
|
223
|
-
function buildSkillUrl(endpoint) {
|
|
224
|
-
try {
|
|
225
|
-
return new URL('skill.md', endpoint.endsWith('/') ? endpoint : `${endpoint}/`).toString();
|
|
226
|
-
}
|
|
227
|
-
catch {
|
|
228
|
-
return `${endpoint.replace(/\/+$/u, '')}/skill.md`;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
function resolveServerSkillPath(server) {
|
|
232
|
-
const localSkillPath = path.join(server.workdir, 'skill.md');
|
|
233
|
-
if (fs.existsSync(localSkillPath)) {
|
|
234
|
-
return localSkillPath;
|
|
235
|
-
}
|
|
236
|
-
return buildSkillUrl(server.endpoint);
|
|
237
|
-
}
|
|
238
|
-
function resolvePluginConfig(pluginConfig, globalConfig, logger) {
|
|
239
|
-
const normalized = isRecord(pluginConfig) ? pluginConfig : {};
|
|
240
|
-
const usedNames = new Set();
|
|
241
|
-
return {
|
|
242
|
-
gatewayUrl: readNonEmptyString(normalized.gatewayUrl) ?? DEFAULT_GATEWAY_URL,
|
|
243
|
-
gatewayToken: readNonEmptyString(normalized.gatewayToken) ??
|
|
244
|
-
readNonEmptyString(globalConfig?.gateway?.auth?.token),
|
|
245
|
-
openclawCliBin: readNonEmptyString(normalized.openclawCliBin) ?? DEFAULT_OPENCLAW_CLI_BIN,
|
|
246
|
-
servers: normalizeServersInput(normalized).map((server, index) => resolveServerConfig(server, index, usedNames, logger)),
|
|
247
|
-
};
|
|
248
|
-
}
|
|
249
|
-
const SERVER_CONFIG_SCHEMA = {
|
|
250
|
-
type: 'object',
|
|
251
|
-
additionalProperties: false,
|
|
252
|
-
properties: {
|
|
253
|
-
enabled: {
|
|
254
|
-
type: 'boolean',
|
|
255
|
-
description: 'Enable or disable background polling for this server',
|
|
256
|
-
default: true,
|
|
257
|
-
},
|
|
258
|
-
name: {
|
|
259
|
-
type: 'string',
|
|
260
|
-
description: 'Server name used for routing, workdir defaults, and diagnostics',
|
|
261
|
-
default: DEFAULT_SERVER_NAME,
|
|
262
|
-
},
|
|
263
|
-
endpoint: {
|
|
264
|
-
type: 'string',
|
|
265
|
-
description: 'EigenFlux API base URL for this server',
|
|
266
|
-
default: DEFAULT_ENDPOINT,
|
|
267
|
-
},
|
|
268
|
-
workdir: {
|
|
269
|
-
type: 'string',
|
|
270
|
-
description: 'Directory used to store server credentials and remembered session state',
|
|
271
|
-
},
|
|
272
|
-
pollInterval: {
|
|
273
|
-
type: 'integer',
|
|
274
|
-
minimum: MIN_POLL_INTERVAL_SEC,
|
|
275
|
-
maximum: MAX_POLL_INTERVAL_SEC,
|
|
276
|
-
description: 'Feed polling interval in seconds for this server',
|
|
277
|
-
default: DEFAULT_POLL_INTERVAL_SEC,
|
|
278
|
-
},
|
|
279
|
-
pmPollInterval: {
|
|
280
|
-
type: 'integer',
|
|
281
|
-
minimum: MIN_POLL_INTERVAL_SEC,
|
|
282
|
-
maximum: MAX_POLL_INTERVAL_SEC,
|
|
283
|
-
description: 'Private message polling interval in seconds for this server',
|
|
284
|
-
default: DEFAULT_PM_POLL_INTERVAL_SEC,
|
|
285
|
-
},
|
|
286
|
-
sessionKey: {
|
|
287
|
-
type: 'string',
|
|
288
|
-
description: 'Target session key used by runtime.subagent and heartbeat fallback',
|
|
289
|
-
default: DEFAULT_SESSION_KEY,
|
|
290
|
-
},
|
|
291
|
-
agentId: {
|
|
292
|
-
type: 'string',
|
|
293
|
-
description: 'Agent id used by Gateway agent and CLI fallbacks',
|
|
294
|
-
default: DEFAULT_AGENT_ID,
|
|
295
|
-
},
|
|
296
|
-
replyChannel: {
|
|
297
|
-
type: 'string',
|
|
298
|
-
description: 'Explicit reply channel used by Gateway agent and CLI fallbacks',
|
|
299
|
-
},
|
|
300
|
-
replyTo: {
|
|
301
|
-
type: 'string',
|
|
302
|
-
description: 'Explicit reply target used by Gateway agent and CLI fallbacks',
|
|
303
|
-
},
|
|
304
|
-
replyAccountId: {
|
|
305
|
-
type: 'string',
|
|
306
|
-
description: 'Optional reply account id for multi-account channel delivery',
|
|
307
|
-
},
|
|
308
|
-
},
|
|
309
|
-
};
|
|
310
202
|
exports.PLUGIN_CONFIG = {
|
|
311
|
-
|
|
312
|
-
DEFAULT_ENDPOINT,
|
|
313
|
-
DEFAULT_GATEWAY_URL,
|
|
203
|
+
DEFAULT_EIGENFLUX_BIN,
|
|
314
204
|
DEFAULT_SESSION_KEY,
|
|
315
205
|
DEFAULT_AGENT_ID,
|
|
316
206
|
DEFAULT_OPENCLAW_CLI_BIN,
|
|
317
|
-
DEFAULT_POLL_INTERVAL_SEC,
|
|
318
|
-
DEFAULT_PM_POLL_INTERVAL_SEC,
|
|
319
|
-
MIN_POLL_INTERVAL_SEC,
|
|
320
|
-
MAX_POLL_INTERVAL_SEC,
|
|
321
207
|
HOST_KIND,
|
|
322
|
-
CREDENTIALS_FILE: 'credentials.json',
|
|
323
208
|
PLUGIN_VERSION,
|
|
324
|
-
USER_AGENT: buildUserAgent(),
|
|
325
209
|
};
|
|
326
|
-
function buildEigenFluxRequestHeaders(accessToken) {
|
|
327
|
-
return {
|
|
328
|
-
Authorization: `Bearer ${accessToken}`,
|
|
329
|
-
'Content-Type': 'application/json',
|
|
330
|
-
'User-Agent': exports.PLUGIN_CONFIG.USER_AGENT,
|
|
331
|
-
'X-Plugin-Ver': exports.PLUGIN_CONFIG.PLUGIN_VERSION,
|
|
332
|
-
'X-Host-Kind': exports.PLUGIN_CONFIG.HOST_KIND,
|
|
333
|
-
};
|
|
334
|
-
}
|
|
335
210
|
exports.PLUGIN_CONFIG_SCHEMA = {
|
|
336
211
|
type: 'object',
|
|
337
212
|
additionalProperties: false,
|
|
338
213
|
properties: {
|
|
339
|
-
|
|
340
|
-
type: 'string',
|
|
341
|
-
description: 'OpenClaw Gateway WebSocket URL used for Gateway RPC fallback',
|
|
342
|
-
default: DEFAULT_GATEWAY_URL,
|
|
343
|
-
},
|
|
344
|
-
gatewayToken: {
|
|
214
|
+
eigenfluxBin: {
|
|
345
215
|
type: 'string',
|
|
346
|
-
description: '
|
|
216
|
+
description: 'Path to the eigenflux CLI binary',
|
|
217
|
+
default: DEFAULT_EIGENFLUX_BIN,
|
|
347
218
|
},
|
|
348
219
|
openclawCliBin: {
|
|
349
220
|
type: 'string',
|
|
350
221
|
description: 'OpenClaw CLI binary used by runtime command fallbacks',
|
|
351
222
|
default: DEFAULT_OPENCLAW_CLI_BIN,
|
|
352
223
|
},
|
|
353
|
-
servers: {
|
|
354
|
-
type: 'array',
|
|
355
|
-
description: 'Server list. When empty or when no server named eigenflux is provided, the plugin prepends a default eigenflux server.',
|
|
356
|
-
default: [],
|
|
357
|
-
items: SERVER_CONFIG_SCHEMA,
|
|
358
|
-
},
|
|
359
224
|
},
|
|
360
225
|
};
|
|
361
226
|
//# sourceMappingURL=config.js.map
|