@phronesis-io/openclaw-eigenflux 0.0.8 → 0.0.9

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.
Files changed (51) hide show
  1. package/README.md +28 -0
  2. package/dist/index.d.ts +9 -23
  3. package/dist/index.js +2265 -457
  4. package/openclaw.plugin.json +5 -1
  5. package/package.json +21 -8
  6. package/dist/agent-prompt-templates.d.ts +0 -19
  7. package/dist/agent-prompt-templates.d.ts.map +0 -1
  8. package/dist/agent-prompt-templates.js +0 -56
  9. package/dist/agent-prompt-templates.js.map +0 -1
  10. package/dist/cli-executor.d.ts +0 -32
  11. package/dist/cli-executor.d.ts.map +0 -1
  12. package/dist/cli-executor.js +0 -75
  13. package/dist/cli-executor.js.map +0 -1
  14. package/dist/config.d.ts +0 -83
  15. package/dist/config.d.ts.map +0 -1
  16. package/dist/config.js +0 -226
  17. package/dist/config.js.map +0 -1
  18. package/dist/credentials-loader.d.ts +0 -29
  19. package/dist/credentials-loader.d.ts.map +0 -1
  20. package/dist/credentials-loader.js +0 -117
  21. package/dist/credentials-loader.js.map +0 -1
  22. package/dist/index.d.ts.map +0 -1
  23. package/dist/index.js.map +0 -1
  24. package/dist/logger.d.ts +0 -12
  25. package/dist/logger.d.ts.map +0 -1
  26. package/dist/logger.js +0 -25
  27. package/dist/logger.js.map +0 -1
  28. package/dist/notification-route-resolver.d.ts +0 -66
  29. package/dist/notification-route-resolver.d.ts.map +0 -1
  30. package/dist/notification-route-resolver.js +0 -603
  31. package/dist/notification-route-resolver.js.map +0 -1
  32. package/dist/notifier.d.ts +0 -39
  33. package/dist/notifier.d.ts.map +0 -1
  34. package/dist/notifier.js +0 -335
  35. package/dist/notifier.js.map +0 -1
  36. package/dist/polling-client.d.ts +0 -86
  37. package/dist/polling-client.d.ts.map +0 -1
  38. package/dist/polling-client.js +0 -158
  39. package/dist/polling-client.js.map +0 -1
  40. package/dist/reply-target.d.ts +0 -8
  41. package/dist/reply-target.d.ts.map +0 -1
  42. package/dist/reply-target.js +0 -104
  43. package/dist/reply-target.js.map +0 -1
  44. package/dist/session-route-memory.d.ts +0 -22
  45. package/dist/session-route-memory.d.ts.map +0 -1
  46. package/dist/session-route-memory.js +0 -117
  47. package/dist/session-route-memory.js.map +0 -1
  48. package/dist/stream-client.d.ts +0 -48
  49. package/dist/stream-client.d.ts.map +0 -1
  50. package/dist/stream-client.js +0 -168
  51. package/dist/stream-client.js.map +0 -1
@@ -1,39 +0,0 @@
1
- import type { OpenClawPluginApi } from 'openclaw/plugin-sdk';
2
- import { type NotificationRouteOverrides } from './config';
3
- import { Logger } from './logger';
4
- export type EigenFluxNotifierConfig = {
5
- eigenfluxBin?: string;
6
- serverName?: string;
7
- sessionKey: string;
8
- agentId: string;
9
- replyChannel?: string;
10
- replyTo?: string;
11
- replyAccountId?: string;
12
- openclawCliBin: string;
13
- sessionStorePath?: string;
14
- routeOverrides?: NotificationRouteOverrides;
15
- };
16
- export declare class EigenFluxNotifier {
17
- private readonly api;
18
- private readonly logger;
19
- private readonly config;
20
- constructor(api: OpenClawPluginApi, logger: Logger, config: EigenFluxNotifierConfig);
21
- deliver(message: string): Promise<boolean>;
22
- private attemptDelivery;
23
- private tryNotifyViaRuntimeSubagent;
24
- private tryNotifyViaRuntimeCommandAgent;
25
- private tryNotifyViaRuntimeHeartbeat;
26
- private tryNotifyViaRuntimeCommandHeartbeat;
27
- private runRuntimeCommand;
28
- private buildAgentCliArgs;
29
- private buildHeartbeatCliArgs;
30
- private resolveHeartbeatDeliveryContext;
31
- private resolveRoute;
32
- /**
33
- * Persist the successful route to the eigenflux CLI config unless it came from
34
- * the remembered config already (no-op when unchanged).
35
- */
36
- private rememberRouteIfChanged;
37
- private logDispatch;
38
- }
39
- //# sourceMappingURL=notifier.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"notifier.d.ts","sourceRoot":"","sources":["../src/notifier.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,KAAK,0BAA0B,EAAE,MAAM,UAAU,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAkBlC,MAAM,MAAM,uBAAuB,GAAG;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,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,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,0BAA0B,CAAC;CAC7C,CAAC;AAqBF,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAoB;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;gBAErC,GAAG,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,uBAAuB;IAM7E,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;YA8ClC,eAAe;YAwCf,2BAA2B;YA0E3B,+BAA+B;YAW/B,4BAA4B;YAuE5B,mCAAmC;YASnC,iBAAiB;IAgD/B,OAAO,CAAC,iBAAiB;IAwBzB,OAAO,CAAC,qBAAqB;IAY7B,OAAO,CAAC,+BAA+B;YAoBzB,YAAY;IAU1B;;;OAGG;YACW,sBAAsB;IA2BpC,OAAO,CAAC,WAAW;CAWpB"}
package/dist/notifier.js DELETED
@@ -1,335 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EigenFluxNotifier = void 0;
4
- const node_crypto_1 = require("node:crypto");
5
- const notification_route_resolver_1 = require("./notification-route-resolver");
6
- const session_route_memory_1 = require("./session-route-memory");
7
- const COMMAND_TIMEOUT_MS = 15000;
8
- // deliver: true runs the full agent loop (LLM + reply + channel send), which can
9
- // take well over a minute on long feed payloads. 3 minutes gives agents plenty
10
- // of room to complete while still bounding a genuinely stuck run.
11
- const SUBAGENT_WAIT_TIMEOUT_MS = 180000;
12
- const HEARTBEAT_REASON = 'plugin:eigenflux';
13
- class EigenFluxNotifier {
14
- constructor(api, logger, config) {
15
- this.api = api;
16
- this.logger = logger;
17
- this.config = config;
18
- }
19
- async deliver(message) {
20
- const initial = await this.resolveRoute();
21
- this.logger.info(`Delivery route resolved: source=${initial.source}, ${formatRouteForLog(initial.route)}, message_preview=${previewMessage(message)}`);
22
- const firstAttempt = await this.attemptDelivery(message, initial.route);
23
- if (firstAttempt.result.ok) {
24
- await this.rememberRouteIfChanged(firstAttempt.finalRoute, initial.source);
25
- this.logDispatch(firstAttempt.result);
26
- return true;
27
- }
28
- // If every transport failed with a remembered route, it may be stale.
29
- // Re-resolve fresh (skipping remembered), then retry the transport chain once.
30
- if (initial.source === 'remembered') {
31
- this.logger.warn(`All transports failed with remembered route; re-resolving without remembered config.`);
32
- const fallback = await this.resolveRoute({ ignoreRemembered: true });
33
- if (fallback.route.sessionKey !== initial.route.sessionKey ||
34
- fallback.route.replyTo !== initial.route.replyTo ||
35
- fallback.route.replyChannel !== initial.route.replyChannel) {
36
- this.logger.info(`Retrying delivery with fresh route: source=${fallback.source}, ${formatRouteForLog(fallback.route)}`);
37
- const retry = await this.attemptDelivery(message, fallback.route);
38
- if (retry.result.ok) {
39
- await this.rememberRouteIfChanged(retry.finalRoute, fallback.source);
40
- this.logDispatch(retry.result);
41
- return true;
42
- }
43
- this.logger.error(`Failed to deliver notification after fresh re-resolve: ${retry.errors.join(' | ')}`);
44
- return false;
45
- }
46
- this.logger.warn('Fresh re-resolve produced the same route; skipping retry.');
47
- }
48
- this.logger.error(`Failed to deliver notification: ${firstAttempt.errors.join(' | ')}`);
49
- return false;
50
- }
51
- async attemptDelivery(message, route) {
52
- const attempts = [
53
- () => this.tryNotifyViaRuntimeSubagent(message, route),
54
- () => this.tryNotifyViaRuntimeCommandAgent(message, route),
55
- () => this.tryNotifyViaRuntimeHeartbeat(message, route),
56
- () => this.tryNotifyViaRuntimeCommandHeartbeat(message),
57
- ];
58
- const errors = [];
59
- for (const attempt of attempts) {
60
- const result = await attempt();
61
- if (result.ok) {
62
- const finalRoute = {
63
- sessionKey: result.sessionKey ?? route.sessionKey,
64
- agentId: route.agentId,
65
- replyChannel: route.replyChannel,
66
- replyTo: route.replyTo,
67
- replyAccountId: route.replyAccountId,
68
- };
69
- return { result, finalRoute, errors };
70
- }
71
- this.logger.warn(`Notification attempt failed: mode=${result.mode}, ${formatRouteForLog(route)}, error=${result.error}`);
72
- errors.push(`${result.mode}: ${result.error}`);
73
- }
74
- return {
75
- result: { ok: false, mode: 'all', error: errors.join(' | ') },
76
- finalRoute: route,
77
- errors,
78
- };
79
- }
80
- async tryNotifyViaRuntimeSubagent(message, route) {
81
- const runtimeSubagent = this.api.runtime?.subagent;
82
- if (!runtimeSubagent || typeof runtimeSubagent.run !== 'function') {
83
- return {
84
- ok: false,
85
- mode: 'runtime.subagent',
86
- error: 'runtime.subagent.run is unavailable',
87
- };
88
- }
89
- try {
90
- this.logger.info(`Attempting runtime.subagent delivery: ${formatRouteForLog(route)}, deliver=true`);
91
- const { runId } = await runtimeSubagent.run({
92
- sessionKey: route.sessionKey,
93
- message,
94
- deliver: true,
95
- idempotencyKey: (0, node_crypto_1.randomUUID)(),
96
- });
97
- // run() only enqueues; wait long enough for the full agent loop (LLM +
98
- // reply + channel send) to complete so we can surface real errors. A
99
- // waitForRun timeout here means "still running" — treat it as success
100
- // and let the subagent finish asynchronously, since retrying via CLI
101
- // would re-run the same agent loop and cause duplicate deliveries.
102
- if (typeof runtimeSubagent.waitForRun === 'function') {
103
- const waited = await runtimeSubagent.waitForRun({
104
- runId,
105
- timeoutMs: SUBAGENT_WAIT_TIMEOUT_MS,
106
- });
107
- if (waited.status === 'error') {
108
- return {
109
- ok: false,
110
- mode: 'runtime.subagent',
111
- error: `subagent run error${waited.error ? `: ${waited.error}` : ''}`,
112
- };
113
- }
114
- }
115
- return {
116
- ok: true,
117
- mode: 'runtime.subagent',
118
- sessionKey: route.sessionKey,
119
- runId,
120
- };
121
- }
122
- catch (error) {
123
- return {
124
- ok: false,
125
- mode: 'runtime.subagent',
126
- error: formatError(error),
127
- };
128
- }
129
- }
130
- async tryNotifyViaRuntimeCommandAgent(message, route) {
131
- return this.runRuntimeCommand('runtime.command.agent', this.buildAgentCliArgs(message, route), route);
132
- }
133
- async tryNotifyViaRuntimeHeartbeat(message, route) {
134
- const runtimeSystem = this.api.runtime?.system;
135
- if (!runtimeSystem ||
136
- typeof runtimeSystem.enqueueSystemEvent !== 'function' ||
137
- typeof runtimeSystem.requestHeartbeatNow !== 'function') {
138
- return {
139
- ok: false,
140
- mode: 'runtime.system.heartbeat',
141
- error: 'runtime.system heartbeat APIs are unavailable',
142
- };
143
- }
144
- try {
145
- const deliveryContext = this.resolveHeartbeatDeliveryContext(route);
146
- this.logger.info(`Attempting runtime.system.heartbeat delivery: ${formatRouteForLog(route)}, delivery_context=${formatDeliveryContextForLog(deliveryContext)}`);
147
- const enqueued = runtimeSystem.enqueueSystemEvent(message, {
148
- sessionKey: route.sessionKey,
149
- ...(deliveryContext ? { deliveryContext } : {}),
150
- });
151
- runtimeSystem.requestHeartbeatNow({
152
- reason: HEARTBEAT_REASON,
153
- coalesceMs: 0,
154
- agentId: route.agentId,
155
- sessionKey: route.sessionKey,
156
- });
157
- return {
158
- ok: true,
159
- mode: 'runtime.system.heartbeat',
160
- sessionKey: route.sessionKey,
161
- detail: enqueued ? 'enqueued' : 'duplicate-enqueued',
162
- };
163
- }
164
- catch (error) {
165
- return {
166
- ok: false,
167
- mode: 'runtime.system.heartbeat',
168
- error: formatError(error),
169
- };
170
- }
171
- }
172
- async tryNotifyViaRuntimeCommandHeartbeat(message) {
173
- const { route } = await this.resolveRoute();
174
- return this.runRuntimeCommand('runtime.command.heartbeat', this.buildHeartbeatCliArgs(message), route);
175
- }
176
- async runRuntimeCommand(mode, argv, route) {
177
- const runtimeCommand = this.api.runtime?.system?.runCommandWithTimeout;
178
- if (typeof runtimeCommand !== 'function') {
179
- return {
180
- ok: false,
181
- mode,
182
- error: 'runtime.system.runCommandWithTimeout is unavailable',
183
- };
184
- }
185
- try {
186
- this.logger.info(`Attempting ${mode} delivery: ${formatRouteForLog(route)}, argv=${formatCommandArgsForLog(argv)}`);
187
- const result = await runtimeCommand(argv, { timeoutMs: COMMAND_TIMEOUT_MS });
188
- if (result.code === 0) {
189
- return {
190
- ok: true,
191
- mode,
192
- sessionKey: route.sessionKey,
193
- };
194
- }
195
- return {
196
- ok: false,
197
- mode,
198
- error: `${formatCommandFailure(result)} (argv=${formatCommandArgsForLog(argv)})`,
199
- };
200
- }
201
- catch (error) {
202
- return {
203
- ok: false,
204
- mode,
205
- error: formatError(error),
206
- };
207
- }
208
- }
209
- buildAgentCliArgs(message, route) {
210
- const args = [
211
- this.config.openclawCliBin,
212
- 'agent',
213
- '--message',
214
- message,
215
- '--agent',
216
- route.agentId,
217
- '--deliver',
218
- ];
219
- if (route.replyChannel) {
220
- args.push('--reply-channel', route.replyChannel);
221
- }
222
- if (route.replyTo) {
223
- args.push('--reply-to', route.replyTo);
224
- }
225
- if (route.replyAccountId) {
226
- args.push('--reply-account', route.replyAccountId);
227
- }
228
- return args;
229
- }
230
- buildHeartbeatCliArgs(message) {
231
- return [
232
- this.config.openclawCliBin,
233
- 'system',
234
- 'event',
235
- '--text',
236
- message,
237
- '--mode',
238
- 'now',
239
- ];
240
- }
241
- resolveHeartbeatDeliveryContext(route) {
242
- if (!route.replyChannel && !route.replyTo && !route.replyAccountId) {
243
- return undefined;
244
- }
245
- return {
246
- ...(route.replyChannel ? { channel: route.replyChannel } : {}),
247
- ...(route.replyTo ? { to: route.replyTo } : {}),
248
- ...(route.replyAccountId ? { accountId: route.replyAccountId } : {}),
249
- };
250
- }
251
- async resolveRoute(options = {}) {
252
- return (0, notification_route_resolver_1.resolveNotificationRoute)(this.config, this.logger, options);
253
- }
254
- /**
255
- * Persist the successful route to the eigenflux CLI config unless it came from
256
- * the remembered config already (no-op when unchanged).
257
- */
258
- async rememberRouteIfChanged(route, source) {
259
- if (!route.sessionKey || !route.agentId) {
260
- return;
261
- }
262
- if ((0, notification_route_resolver_1.isInternalSessionKey)(route.sessionKey)) {
263
- return;
264
- }
265
- if (!route.replyChannel || !route.replyTo) {
266
- return;
267
- }
268
- if (source === 'remembered') {
269
- this.logger.debug(`Skipping remembered-route write; route came from config (session_key=${route.sessionKey})`);
270
- return;
271
- }
272
- await (0, session_route_memory_1.writeStoredNotificationRoute)(this.config.eigenfluxBin, this.config.serverName, route, this.logger);
273
- }
274
- logDispatch(result) {
275
- const details = [
276
- `mode=${result.mode}`,
277
- result.sessionKey ? `session_key=${result.sessionKey}` : null,
278
- result.runId ? `run_id=${result.runId}` : null,
279
- result.detail ? `detail=${result.detail}` : null,
280
- ]
281
- .filter(Boolean)
282
- .join(', ');
283
- this.logger.info(`Notification dispatched: ${details}`);
284
- }
285
- }
286
- exports.EigenFluxNotifier = EigenFluxNotifier;
287
- function formatCommandFailure(result) {
288
- return (result.stderr?.trim() ||
289
- result.stdout?.trim() ||
290
- `command exited with ${result.code ?? 'unknown'}`);
291
- }
292
- function formatError(error) {
293
- if (error instanceof Error) {
294
- return `${error.name}: ${error.message}`;
295
- }
296
- return String(error);
297
- }
298
- function formatRouteForLog(route) {
299
- return [
300
- `session_key=${route.sessionKey}`,
301
- `agent_id=${route.agentId}`,
302
- `channel=${route.replyChannel ?? 'n/a'}`,
303
- `to=${route.replyTo ?? 'n/a'}`,
304
- `account=${route.replyAccountId ?? 'n/a'}`,
305
- ].join(', ');
306
- }
307
- function formatDeliveryContextForLog(deliveryContext) {
308
- if (!deliveryContext) {
309
- return 'none';
310
- }
311
- return [
312
- `channel=${deliveryContext.channel ?? 'n/a'}`,
313
- `to=${deliveryContext.to ?? 'n/a'}`,
314
- `account=${deliveryContext.accountId ?? 'n/a'}`,
315
- ].join(', ');
316
- }
317
- function previewMessage(message, maxLength = 120) {
318
- const singleLine = message.replace(/\s+/gu, ' ').trim();
319
- if (singleLine.length <= maxLength) {
320
- return JSON.stringify(singleLine);
321
- }
322
- return JSON.stringify(`${singleLine.slice(0, maxLength - 3)}...`);
323
- }
324
- function formatCommandArgsForLog(argv) {
325
- const sanitized = [...argv];
326
- for (let index = 0; index < sanitized.length; index += 1) {
327
- if (sanitized[index] === '--message' || sanitized[index] === '--text') {
328
- if (typeof sanitized[index + 1] === 'string') {
329
- sanitized[index + 1] = `<len:${sanitized[index + 1].length}>`;
330
- }
331
- }
332
- }
333
- return JSON.stringify(sanitized);
334
- }
335
- //# sourceMappingURL=notifier.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"notifier.js","sourceRoot":"","sources":["../src/notifier.ts"],"names":[],"mappings":"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"}
@@ -1,86 +0,0 @@
1
- /**
2
- * Polling client for EigenFlux feed updates.
3
- * Uses the eigenflux CLI (`eigenflux feed poll`) instead of direct HTTP calls.
4
- */
5
- import { Logger } from './logger';
6
- export declare const POLL_INTERVAL_CONFIG_KEY = "feed_poll_interval";
7
- export declare const DEFAULT_POLL_INTERVAL_SEC = 600;
8
- export declare const MIN_POLL_INTERVAL_SEC = 10;
9
- export declare const MAX_POLL_INTERVAL_SEC: number;
10
- /**
11
- * Reads the feed poll interval (in seconds) from the eigenflux CLI config
12
- * (`eigenflux config get --key feed_poll_interval`). Values are stored as
13
- * decimal-string seconds per the config KV conventions. Falls back to 600
14
- * (10 minutes) when the key is unset, the value is invalid, out of the
15
- * supported range [10s, 86400s], or the CLI call fails.
16
- */
17
- export declare function readPollIntervalSec(eigenfluxBin: string, serverName: string, logger: Logger): Promise<number>;
18
- export interface FeedItem {
19
- item_id: string;
20
- summary?: string;
21
- broadcast_type: string;
22
- domains?: string[];
23
- keywords?: string[];
24
- group_id?: string;
25
- source_type?: string;
26
- url?: string;
27
- updated_at: number;
28
- }
29
- export interface FeedNotification {
30
- notification_id: string;
31
- type: string;
32
- content: string;
33
- created_at: number;
34
- }
35
- export interface FeedResponseData {
36
- items: FeedItem[];
37
- has_more: boolean;
38
- notifications: FeedNotification[];
39
- }
40
- export interface FeedResponse {
41
- code: number;
42
- msg: string;
43
- data: FeedResponseData;
44
- }
45
- export interface PollingClientConfig {
46
- serverName: string;
47
- eigenfluxBin: string;
48
- /**
49
- * Resolves the seconds to wait before the next poll. Invoked after every
50
- * poll completes so the interval can be changed at runtime via the
51
- * eigenflux CLI config (`pollInterval` key).
52
- */
53
- resolvePollIntervalSec: () => Promise<number>;
54
- logger: Logger;
55
- onFeedPolled: (payload: FeedResponse) => Promise<void>;
56
- onAuthRequired: (event: AuthRequiredEvent) => Promise<void>;
57
- }
58
- export interface AuthRequiredEvent {
59
- reason: 'auth_required';
60
- }
61
- export type PollResult = {
62
- kind: 'success';
63
- payload: FeedResponse;
64
- } | {
65
- kind: 'auth_required';
66
- authEvent: AuthRequiredEvent;
67
- } | {
68
- kind: 'error';
69
- error: Error;
70
- };
71
- export interface PollOnceOptions {
72
- notifyFeed?: boolean;
73
- notifyAuthRequired?: boolean;
74
- }
75
- export declare class EigenFluxPollingClient {
76
- private config;
77
- private timeoutId;
78
- private isRunning;
79
- private activePoll;
80
- constructor(config: PollingClientConfig);
81
- start(): Promise<void>;
82
- stop(): void;
83
- private scheduleNext;
84
- pollOnce(options?: PollOnceOptions): Promise<PollResult>;
85
- }
86
- //# sourceMappingURL=polling-client.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"polling-client.d.ts","sourceRoot":"","sources":["../src/polling-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,eAAO,MAAM,wBAAwB,uBAAuB,CAAC;AAC7D,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAC7C,eAAO,MAAM,qBAAqB,KAAK,CAAC;AACxC,eAAO,MAAM,qBAAqB,QAAe,CAAC;AAElD;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CACvC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CAqCjB;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,EAAE,gBAAgB,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,gBAAgB,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,sBAAsB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,cAAc,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7D;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,eAAe,CAAC;CACzB;AAED,MAAM,MAAM,UAAU,GAClB;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,YAAY,CAAC;CACvB,GACD;IACE,IAAI,EAAE,eAAe,CAAC;IACtB,SAAS,EAAE,iBAAiB,CAAC;CAC9B,GACD;IACE,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,KAAK,CAAC;CACd,CAAC;AAEN,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,qBAAa,sBAAsB;IACjC,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAoC;gBAE1C,MAAM,EAAE,mBAAmB;IAIjC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB5B,IAAI,IAAI,IAAI;YAcE,YAAY;IAoCpB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,UAAU,CAAC;CAsEnE"}
@@ -1,158 +0,0 @@
1
- "use strict";
2
- /**
3
- * Polling client for EigenFlux feed updates.
4
- * Uses the eigenflux CLI (`eigenflux feed poll`) instead of direct HTTP calls.
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.EigenFluxPollingClient = exports.MAX_POLL_INTERVAL_SEC = exports.MIN_POLL_INTERVAL_SEC = exports.DEFAULT_POLL_INTERVAL_SEC = exports.POLL_INTERVAL_CONFIG_KEY = void 0;
8
- exports.readPollIntervalSec = readPollIntervalSec;
9
- const cli_executor_1 = require("./cli-executor");
10
- exports.POLL_INTERVAL_CONFIG_KEY = 'feed_poll_interval';
11
- exports.DEFAULT_POLL_INTERVAL_SEC = 600;
12
- exports.MIN_POLL_INTERVAL_SEC = 10;
13
- exports.MAX_POLL_INTERVAL_SEC = 24 * 60 * 60;
14
- /**
15
- * Reads the feed poll interval (in seconds) from the eigenflux CLI config
16
- * (`eigenflux config get --key feed_poll_interval`). Values are stored as
17
- * decimal-string seconds per the config KV conventions. Falls back to 600
18
- * (10 minutes) when the key is unset, the value is invalid, out of the
19
- * supported range [10s, 86400s], or the CLI call fails.
20
- */
21
- async function readPollIntervalSec(eigenfluxBin, serverName, logger) {
22
- const result = await (0, cli_executor_1.execEigenflux)(eigenfluxBin, ['config', 'get', '--key', exports.POLL_INTERVAL_CONFIG_KEY, '--server', serverName, '--format', 'json'], { logger });
23
- if (result.kind !== 'success' || result.data === undefined || result.data === null) {
24
- return exports.DEFAULT_POLL_INTERVAL_SEC;
25
- }
26
- let numeric;
27
- if (typeof result.data === 'number' && Number.isFinite(result.data)) {
28
- numeric = result.data;
29
- }
30
- else if (typeof result.data === 'string') {
31
- const parsed = Number(result.data.trim());
32
- if (Number.isFinite(parsed)) {
33
- numeric = parsed;
34
- }
35
- }
36
- if (numeric === undefined) {
37
- logger.warn(`Ignoring non-numeric pollInterval from eigenflux config (server=${serverName}, value=${JSON.stringify(result.data)}); using ${exports.DEFAULT_POLL_INTERVAL_SEC}s`);
38
- return exports.DEFAULT_POLL_INTERVAL_SEC;
39
- }
40
- const floored = Math.floor(numeric);
41
- if (floored < exports.MIN_POLL_INTERVAL_SEC || floored > exports.MAX_POLL_INTERVAL_SEC) {
42
- logger.warn(`pollInterval ${floored}s from eigenflux config (server=${serverName}) is outside [${exports.MIN_POLL_INTERVAL_SEC}s, ${exports.MAX_POLL_INTERVAL_SEC}s]; using ${exports.DEFAULT_POLL_INTERVAL_SEC}s`);
43
- return exports.DEFAULT_POLL_INTERVAL_SEC;
44
- }
45
- return floored;
46
- }
47
- class EigenFluxPollingClient {
48
- constructor(config) {
49
- this.timeoutId = null;
50
- this.isRunning = false;
51
- this.activePoll = null;
52
- this.config = config;
53
- }
54
- async start() {
55
- if (this.isRunning) {
56
- this.config.logger.warn('Polling client already running');
57
- return;
58
- }
59
- this.isRunning = true;
60
- this.config.logger.info(`Starting polling client for server=${this.config.serverName}`);
61
- // Initial fetch, then self-schedule subsequent polls using the interval
62
- // freshly resolved from the eigenflux CLI config after each run.
63
- await this.pollOnce();
64
- this.scheduleNext();
65
- }
66
- stop() {
67
- if (!this.isRunning) {
68
- return;
69
- }
70
- this.config.logger.info(`Stopping polling client for server=${this.config.serverName}`);
71
- this.isRunning = false;
72
- if (this.timeoutId) {
73
- clearTimeout(this.timeoutId);
74
- this.timeoutId = null;
75
- }
76
- }
77
- async scheduleNext() {
78
- if (!this.isRunning) {
79
- return;
80
- }
81
- let intervalSec;
82
- try {
83
- intervalSec = await this.config.resolvePollIntervalSec();
84
- }
85
- catch (error) {
86
- this.config.logger.warn(`Failed to resolve pollInterval for server=${this.config.serverName}: ${error instanceof Error ? error.message : String(error)}; using ${exports.DEFAULT_POLL_INTERVAL_SEC}s`);
87
- intervalSec = exports.DEFAULT_POLL_INTERVAL_SEC;
88
- }
89
- if (!this.isRunning) {
90
- return;
91
- }
92
- this.config.logger.debug(`Scheduling next feed poll for server=${this.config.serverName} in ${intervalSec}s`);
93
- this.timeoutId = setTimeout(() => {
94
- this.timeoutId = null;
95
- this.pollOnce()
96
- .catch((err) => {
97
- this.config.logger.error(`Polling error: ${err instanceof Error ? err.message : String(err)}`);
98
- })
99
- .finally(() => {
100
- this.scheduleNext();
101
- });
102
- }, intervalSec * 1000);
103
- }
104
- async pollOnce(options = {}) {
105
- if (this.activePoll) {
106
- this.config.logger.warn('Skipping feed poll because a previous poll is still in progress');
107
- return this.activePoll;
108
- }
109
- const run = async () => {
110
- const notifyFeed = options.notifyFeed ?? true;
111
- const notifyAuthRequired = options.notifyAuthRequired ?? true;
112
- try {
113
- this.config.logger.info(`Polling feed via CLI for server=${this.config.serverName}`);
114
- const result = await (0, cli_executor_1.execEigenflux)(this.config.eigenfluxBin, ['feed', 'poll', '--limit', '20', '--action', 'refresh', '-s', this.config.serverName, '-f', 'json'], { logger: this.config.logger });
115
- if (result.kind === 'auth_required') {
116
- const authEvent = { reason: 'auth_required' };
117
- if (notifyAuthRequired) {
118
- await this.config.onAuthRequired(authEvent);
119
- }
120
- return { kind: 'auth_required', authEvent };
121
- }
122
- if (result.kind === 'not_installed') {
123
- return {
124
- kind: 'error',
125
- error: new Error(`eigenflux CLI not installed (bin=${result.bin})`),
126
- };
127
- }
128
- if (result.kind === 'error') {
129
- return { kind: 'error', error: result.error };
130
- }
131
- // Reconstruct full FeedResponse envelope from CLI data output
132
- const feedResponse = {
133
- code: 0,
134
- msg: 'success',
135
- data: result.data,
136
- };
137
- const items = feedResponse.data.items ?? [];
138
- const notifications = feedResponse.data.notifications ?? [];
139
- this.config.logger.info(`Polled feed: ${items.length} items, notifications=${notifications.length}, has_more=${feedResponse.data.has_more}`);
140
- if (notifyFeed && (items.length > 0 || notifications.length > 0)) {
141
- await this.config.onFeedPolled(feedResponse);
142
- }
143
- return { kind: 'success', payload: feedResponse };
144
- }
145
- catch (error) {
146
- const normalized = error instanceof Error ? error : new Error(String(error));
147
- this.config.logger.error(`Failed to poll feed for server=${this.config.serverName}: ${normalized.message}`);
148
- return { kind: 'error', error: normalized };
149
- }
150
- };
151
- this.activePoll = run().finally(() => {
152
- this.activePoll = null;
153
- });
154
- return this.activePoll;
155
- }
156
- }
157
- exports.EigenFluxPollingClient = EigenFluxPollingClient;
158
- //# sourceMappingURL=polling-client.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"polling-client.js","sourceRoot":"","sources":["../src/polling-client.ts"],"names":[],"mappings":"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"}