@rainfall-devkit/sdk 0.1.8 → 0.2.1
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 +51 -0
- package/dist/chunk-7MRE4ZVI.mjs +662 -0
- package/dist/chunk-AQFC7YAX.mjs +27 -0
- package/dist/chunk-EI7SJH5K.mjs +85 -0
- package/dist/chunk-NTTAVKRT.mjs +89 -0
- package/dist/chunk-RVKW5KBT.mjs +269 -0
- package/dist/chunk-V5QWJVLC.mjs +662 -0
- package/dist/chunk-VDPKDC3R.mjs +869 -0
- package/dist/chunk-WOITG5TG.mjs +84 -0
- package/dist/chunk-XAHJQRBJ.mjs +269 -0
- package/dist/chunk-XEQ6U3JQ.mjs +269 -0
- package/dist/cli/index.js +3797 -632
- package/dist/cli/index.mjs +453 -36
- package/dist/config-7UT7GYSN.mjs +16 -0
- package/dist/config-DDTQQBN7.mjs +14 -0
- package/dist/config-MD45VGWD.mjs +14 -0
- package/dist/config-ZKNHII2A.mjs +8 -0
- package/dist/daemon/index.d.mts +168 -0
- package/dist/daemon/index.d.ts +168 -0
- package/dist/daemon/index.js +3182 -0
- package/dist/daemon/index.mjs +1548 -0
- package/dist/errors-BMPseAnM.d.mts +47 -0
- package/dist/errors-BMPseAnM.d.ts +47 -0
- package/dist/errors-CZdRoYyw.d.ts +332 -0
- package/dist/errors-Chjq1Mev.d.mts +332 -0
- package/dist/index.d.mts +249 -2
- package/dist/index.d.ts +249 -2
- package/dist/index.js +1247 -3
- package/dist/index.mjs +227 -2
- package/dist/listeners-B5Vy9Ao5.d.ts +372 -0
- package/dist/listeners-BbYIaNCs.d.mts +372 -0
- package/dist/listeners-CP2A9J_2.d.ts +372 -0
- package/dist/listeners-CTRSofnm.d.mts +372 -0
- package/dist/listeners-CYI-YwIF.d.mts +372 -0
- package/dist/listeners-DRwITBW_.d.mts +372 -0
- package/dist/listeners-DrMrvFT5.d.ts +372 -0
- package/dist/listeners-MNAnpZj-.d.mts +372 -0
- package/dist/listeners-PZI7iT85.d.ts +372 -0
- package/dist/listeners-QJeEtLbV.d.ts +372 -0
- package/dist/listeners-hp0Ib2Ox.d.ts +372 -0
- package/dist/listeners-jLwetUnx.d.mts +372 -0
- package/dist/mcp.d.mts +7 -2
- package/dist/mcp.d.ts +7 -2
- package/dist/mcp.js +92 -1
- package/dist/mcp.mjs +1 -1
- package/dist/sdk-4OvXPr8E.d.mts +1054 -0
- package/dist/sdk-4OvXPr8E.d.ts +1054 -0
- package/dist/sdk-CJ9g5lFo.d.mts +772 -0
- package/dist/sdk-CJ9g5lFo.d.ts +772 -0
- package/dist/sdk-CN1ezZrI.d.mts +1054 -0
- package/dist/sdk-CN1ezZrI.d.ts +1054 -0
- package/dist/sdk-DD1OeGRJ.d.mts +871 -0
- package/dist/sdk-DD1OeGRJ.d.ts +871 -0
- package/dist/sdk-Xw0BjsLd.d.mts +1054 -0
- package/dist/sdk-Xw0BjsLd.d.ts +1054 -0
- package/dist/types-GnRAfH-h.d.mts +489 -0
- package/dist/types-GnRAfH-h.d.ts +489 -0
- package/package.json +17 -5
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
EdgeNodeSecurity,
|
|
3
|
+
createEdgeNodeSecurity
|
|
4
|
+
} from "./chunk-XEQ6U3JQ.mjs";
|
|
5
|
+
import {
|
|
6
|
+
RainfallDaemonContext,
|
|
7
|
+
RainfallListenerRegistry,
|
|
8
|
+
RainfallNetworkedExecutor,
|
|
9
|
+
createCronWorkflow,
|
|
10
|
+
createFileWatcherWorkflow
|
|
11
|
+
} from "./chunk-7MRE4ZVI.mjs";
|
|
1
12
|
import {
|
|
2
13
|
AuthenticationError,
|
|
3
14
|
NetworkError,
|
|
@@ -10,21 +21,235 @@ import {
|
|
|
10
21
|
TimeoutError,
|
|
11
22
|
ToolNotFoundError,
|
|
12
23
|
ValidationError
|
|
13
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-VDPKDC3R.mjs";
|
|
25
|
+
|
|
26
|
+
// src/security/edge-client.ts
|
|
27
|
+
import { readFileSync, existsSync } from "fs";
|
|
28
|
+
import { join } from "path";
|
|
29
|
+
var SecureEdgeClient = class {
|
|
30
|
+
client;
|
|
31
|
+
security;
|
|
32
|
+
edgeNodeId;
|
|
33
|
+
edgeNodeSecret;
|
|
34
|
+
keysPath;
|
|
35
|
+
jwtPayload;
|
|
36
|
+
keyPair;
|
|
37
|
+
constructor(config) {
|
|
38
|
+
this.client = config.client;
|
|
39
|
+
this.edgeNodeId = config.edgeNodeId;
|
|
40
|
+
this.edgeNodeSecret = config.edgeNodeSecret;
|
|
41
|
+
this.keysPath = config.keysPath;
|
|
42
|
+
this.security = new EdgeNodeSecurity({
|
|
43
|
+
backendSecret: config.backendSecret
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Initialize the secure client
|
|
48
|
+
*/
|
|
49
|
+
async initialize() {
|
|
50
|
+
await this.security.initialize();
|
|
51
|
+
await this.loadKeyPair();
|
|
52
|
+
this.jwtPayload = this.security.validateJWT(this.edgeNodeSecret);
|
|
53
|
+
if (this.jwtPayload.edgeNodeId !== this.edgeNodeId) {
|
|
54
|
+
throw new Error("JWT edge node ID mismatch");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Load key pair from disk
|
|
59
|
+
*/
|
|
60
|
+
async loadKeyPair() {
|
|
61
|
+
const publicKeyPath = join(this.keysPath, "edge-node.pub");
|
|
62
|
+
const privateKeyPath = join(this.keysPath, "edge-node.key");
|
|
63
|
+
if (!existsSync(publicKeyPath) || !existsSync(privateKeyPath)) {
|
|
64
|
+
throw new Error("Key pair not found. Run: rainfall edge generate-keys");
|
|
65
|
+
}
|
|
66
|
+
this.keyPair = {
|
|
67
|
+
publicKey: readFileSync(publicKeyPath, "utf-8"),
|
|
68
|
+
privateKey: readFileSync(privateKeyPath, "utf-8")
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Get public key for sharing with backend
|
|
73
|
+
*/
|
|
74
|
+
getPublicKey() {
|
|
75
|
+
if (!this.keyPair) {
|
|
76
|
+
throw new Error("Key pair not loaded");
|
|
77
|
+
}
|
|
78
|
+
return this.keyPair.publicKey;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Send heartbeat with authentication
|
|
82
|
+
*/
|
|
83
|
+
async heartbeat() {
|
|
84
|
+
this.requireAuth();
|
|
85
|
+
return this.client.request("/edge/heartbeat", {
|
|
86
|
+
method: "POST",
|
|
87
|
+
body: {
|
|
88
|
+
edgeNodeId: this.edgeNodeId,
|
|
89
|
+
timestamp: Date.now()
|
|
90
|
+
},
|
|
91
|
+
headers: {
|
|
92
|
+
"Authorization": `Bearer ${this.edgeNodeSecret}`
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Claim a job from the queue
|
|
98
|
+
*/
|
|
99
|
+
async claimJob() {
|
|
100
|
+
this.requireAuth();
|
|
101
|
+
const job = await this.client.request("/edge/claim-job", {
|
|
102
|
+
method: "POST",
|
|
103
|
+
body: {
|
|
104
|
+
edgeNodeId: this.edgeNodeId,
|
|
105
|
+
subscriberId: this.jwtPayload.subscriberId
|
|
106
|
+
},
|
|
107
|
+
headers: {
|
|
108
|
+
"Authorization": `Bearer ${this.edgeNodeSecret}`
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
if (job && job.encrypted && job.params) {
|
|
112
|
+
const decrypted = await this.decryptJobParams(job.params);
|
|
113
|
+
return { ...job, params: decrypted };
|
|
114
|
+
}
|
|
115
|
+
return job;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Submit job result
|
|
119
|
+
*/
|
|
120
|
+
async submitJobResult(result) {
|
|
121
|
+
this.requireAuth();
|
|
122
|
+
let encryptedOutput;
|
|
123
|
+
if (result.output) {
|
|
124
|
+
encryptedOutput = await this.encryptJobResult(result.output);
|
|
125
|
+
}
|
|
126
|
+
await this.client.request("/edge/submit-job-result", {
|
|
127
|
+
method: "POST",
|
|
128
|
+
body: {
|
|
129
|
+
edgeNodeId: this.edgeNodeId,
|
|
130
|
+
subscriberId: this.jwtPayload.subscriberId,
|
|
131
|
+
result: {
|
|
132
|
+
...result,
|
|
133
|
+
output: encryptedOutput,
|
|
134
|
+
encrypted: !!encryptedOutput
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
headers: {
|
|
138
|
+
"Authorization": `Bearer ${this.edgeNodeSecret}`
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Queue a job for processing
|
|
144
|
+
*/
|
|
145
|
+
async queueJob(type, params, targetPublicKey) {
|
|
146
|
+
this.requireAuth();
|
|
147
|
+
let encryptedParams;
|
|
148
|
+
let encrypted = false;
|
|
149
|
+
if (targetPublicKey) {
|
|
150
|
+
encryptedParams = await this.encryptJobParamsForTarget(
|
|
151
|
+
JSON.stringify(params),
|
|
152
|
+
targetPublicKey
|
|
153
|
+
);
|
|
154
|
+
encrypted = true;
|
|
155
|
+
}
|
|
156
|
+
return this.client.request("/edge/queue-job", {
|
|
157
|
+
method: "POST",
|
|
158
|
+
body: {
|
|
159
|
+
edgeNodeId: this.edgeNodeId,
|
|
160
|
+
subscriberId: this.jwtPayload.subscriberId,
|
|
161
|
+
job: {
|
|
162
|
+
type,
|
|
163
|
+
params: encryptedParams || JSON.stringify(params),
|
|
164
|
+
encrypted
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
headers: {
|
|
168
|
+
"Authorization": `Bearer ${this.edgeNodeSecret}`
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Decrypt job params received from backend
|
|
174
|
+
*/
|
|
175
|
+
async decryptJobParams(encryptedParams) {
|
|
176
|
+
const encrypted = JSON.parse(encryptedParams);
|
|
177
|
+
return this.security.decryptFromBackend(encrypted);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Encrypt job result for sending to backend
|
|
181
|
+
*/
|
|
182
|
+
async encryptJobResult(output) {
|
|
183
|
+
const encrypted = await this.security.encryptLocal(output, this.keyPair.privateKey);
|
|
184
|
+
return JSON.stringify(encrypted);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Encrypt job params for a specific target edge node
|
|
188
|
+
*/
|
|
189
|
+
async encryptJobParamsForTarget(params, targetPublicKey) {
|
|
190
|
+
const encrypted = await this.security.encryptForEdgeNode(params, targetPublicKey);
|
|
191
|
+
return JSON.stringify(encrypted);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Check if client is authenticated
|
|
195
|
+
*/
|
|
196
|
+
requireAuth() {
|
|
197
|
+
if (!this.jwtPayload) {
|
|
198
|
+
throw new Error("Client not authenticated. Call initialize() first.");
|
|
199
|
+
}
|
|
200
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
201
|
+
if (this.jwtPayload.expiresAt < now) {
|
|
202
|
+
throw new Error("JWT token expired. Re-register edge node.");
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Get current authentication status
|
|
207
|
+
*/
|
|
208
|
+
getAuthStatus() {
|
|
209
|
+
if (!this.jwtPayload) {
|
|
210
|
+
return { authenticated: false };
|
|
211
|
+
}
|
|
212
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
213
|
+
return {
|
|
214
|
+
authenticated: this.jwtPayload.expiresAt > now,
|
|
215
|
+
edgeNodeId: this.jwtPayload.edgeNodeId,
|
|
216
|
+
subscriberId: this.jwtPayload.subscriberId,
|
|
217
|
+
expiresAt: this.jwtPayload.expiresAt,
|
|
218
|
+
scopes: this.jwtPayload.scopes
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
async function createSecureEdgeClient(client, options) {
|
|
223
|
+
const secureClient = new SecureEdgeClient({
|
|
224
|
+
client,
|
|
225
|
+
...options
|
|
226
|
+
});
|
|
227
|
+
await secureClient.initialize();
|
|
228
|
+
return secureClient;
|
|
229
|
+
}
|
|
14
230
|
|
|
15
231
|
// src/index.ts
|
|
16
232
|
var VERSION = "0.1.0";
|
|
17
233
|
export {
|
|
18
234
|
AuthenticationError,
|
|
235
|
+
EdgeNodeSecurity,
|
|
19
236
|
NetworkError,
|
|
20
237
|
NotFoundError,
|
|
21
238
|
Rainfall,
|
|
22
239
|
RainfallClient,
|
|
240
|
+
RainfallDaemonContext,
|
|
23
241
|
RainfallError,
|
|
242
|
+
RainfallListenerRegistry,
|
|
243
|
+
RainfallNetworkedExecutor,
|
|
24
244
|
RateLimitError,
|
|
245
|
+
SecureEdgeClient,
|
|
25
246
|
ServerError,
|
|
26
247
|
TimeoutError,
|
|
27
248
|
ToolNotFoundError,
|
|
28
249
|
VERSION,
|
|
29
|
-
ValidationError
|
|
250
|
+
ValidationError,
|
|
251
|
+
createCronWorkflow,
|
|
252
|
+
createEdgeNodeSecurity,
|
|
253
|
+
createFileWatcherWorkflow,
|
|
254
|
+
createSecureEdgeClient
|
|
30
255
|
};
|
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
import { a as Rainfall } from './sdk-4OvXPr8E.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Rainfall Networked Executor - Distributed job execution via Rainfall API
|
|
5
|
+
*
|
|
6
|
+
* This service enables multi-computer networked executions without direct Redis access.
|
|
7
|
+
* All communication goes through the authenticated Rainfall API.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
interface NodeCapabilities {
|
|
11
|
+
/** Can execute local commands/shell */
|
|
12
|
+
localExec?: boolean;
|
|
13
|
+
/** Can watch files for changes */
|
|
14
|
+
fileWatch?: boolean;
|
|
15
|
+
/** Can listen to passive events (webhooks, etc.) */
|
|
16
|
+
passiveListen?: boolean;
|
|
17
|
+
/** Can execute browser automation */
|
|
18
|
+
browser?: boolean;
|
|
19
|
+
/** Custom capability flags */
|
|
20
|
+
custom?: string[];
|
|
21
|
+
}
|
|
22
|
+
interface EdgeNodeRegistration {
|
|
23
|
+
edgeNodeId: string;
|
|
24
|
+
hostname: string;
|
|
25
|
+
capabilities: string[];
|
|
26
|
+
wsPort?: number;
|
|
27
|
+
httpPort?: number;
|
|
28
|
+
registeredAt: string;
|
|
29
|
+
}
|
|
30
|
+
interface QueuedJob {
|
|
31
|
+
jobId: string;
|
|
32
|
+
toolId: string;
|
|
33
|
+
params: Record<string, unknown>;
|
|
34
|
+
status: 'queued' | 'running' | 'completed' | 'failed';
|
|
35
|
+
executionMode: 'local-only' | 'distributed' | 'any';
|
|
36
|
+
requesterEdgeNodeId?: string;
|
|
37
|
+
executorEdgeNodeId?: string;
|
|
38
|
+
createdAt: string;
|
|
39
|
+
startedAt?: string;
|
|
40
|
+
completedAt?: string;
|
|
41
|
+
result?: unknown;
|
|
42
|
+
error?: string;
|
|
43
|
+
}
|
|
44
|
+
interface NetworkedExecutorOptions {
|
|
45
|
+
/** WebSocket port for receiving push jobs */
|
|
46
|
+
wsPort?: number;
|
|
47
|
+
/** HTTP port for health checks */
|
|
48
|
+
httpPort?: number;
|
|
49
|
+
/** Edge node capabilities */
|
|
50
|
+
capabilities?: NodeCapabilities;
|
|
51
|
+
/** Hostname identifier */
|
|
52
|
+
hostname?: string;
|
|
53
|
+
}
|
|
54
|
+
declare class RainfallNetworkedExecutor {
|
|
55
|
+
private rainfall;
|
|
56
|
+
private options;
|
|
57
|
+
private edgeNodeId?;
|
|
58
|
+
private jobCallbacks;
|
|
59
|
+
private resultPollingInterval?;
|
|
60
|
+
constructor(rainfall: Rainfall, options?: NetworkedExecutorOptions);
|
|
61
|
+
/**
|
|
62
|
+
* Register this edge node with the Rainfall backend
|
|
63
|
+
*/
|
|
64
|
+
registerEdgeNode(): Promise<string>;
|
|
65
|
+
/**
|
|
66
|
+
* Unregister this edge node on shutdown
|
|
67
|
+
*/
|
|
68
|
+
unregisterEdgeNode(): Promise<void>;
|
|
69
|
+
/**
|
|
70
|
+
* Queue a tool execution for distributed processing
|
|
71
|
+
* Non-blocking - returns immediately with a job ID
|
|
72
|
+
*/
|
|
73
|
+
queueToolExecution(toolId: string, params: Record<string, unknown>, options?: {
|
|
74
|
+
executionMode?: 'local-only' | 'distributed' | 'any';
|
|
75
|
+
callback?: (result: unknown, error?: string) => void;
|
|
76
|
+
}): Promise<string>;
|
|
77
|
+
/**
|
|
78
|
+
* Get status of a queued job
|
|
79
|
+
*/
|
|
80
|
+
getJobStatus(jobId: string): Promise<QueuedJob | null>;
|
|
81
|
+
/**
|
|
82
|
+
* Subscribe to job results via polling (WebSocket fallback)
|
|
83
|
+
* In the future, this will use WebSocket push from ApresMoi
|
|
84
|
+
*/
|
|
85
|
+
subscribeToResults(callback: (jobId: string, result: unknown, error?: string) => void): Promise<void>;
|
|
86
|
+
private onResultReceived?;
|
|
87
|
+
/**
|
|
88
|
+
* Start polling for job results (fallback until WebSocket push is ready)
|
|
89
|
+
*/
|
|
90
|
+
private startResultPolling;
|
|
91
|
+
/**
|
|
92
|
+
* Claim a job for execution on this edge node
|
|
93
|
+
*/
|
|
94
|
+
claimJob(): Promise<QueuedJob | null>;
|
|
95
|
+
/**
|
|
96
|
+
* Submit job result after execution
|
|
97
|
+
*/
|
|
98
|
+
submitJobResult(jobId: string, result: unknown, error?: string): Promise<void>;
|
|
99
|
+
/**
|
|
100
|
+
* Get this edge node's ID
|
|
101
|
+
*/
|
|
102
|
+
getEdgeNodeId(): string | undefined;
|
|
103
|
+
/**
|
|
104
|
+
* Build capabilities list from options
|
|
105
|
+
*/
|
|
106
|
+
private buildCapabilitiesList;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Rainfall Daemon Context - Persistent memory and session state
|
|
111
|
+
*
|
|
112
|
+
* Provides:
|
|
113
|
+
* - Persistent memory storage (local + cloud sync)
|
|
114
|
+
* - Session context for ongoing conversations/workflows
|
|
115
|
+
* - Tool execution history
|
|
116
|
+
* - Local state management
|
|
117
|
+
*/
|
|
118
|
+
|
|
119
|
+
interface MemoryEntry {
|
|
120
|
+
id: string;
|
|
121
|
+
content: string;
|
|
122
|
+
keywords: string[];
|
|
123
|
+
timestamp: string;
|
|
124
|
+
source?: string;
|
|
125
|
+
metadata?: Record<string, unknown>;
|
|
126
|
+
}
|
|
127
|
+
interface SessionContext {
|
|
128
|
+
id: string;
|
|
129
|
+
startedAt: string;
|
|
130
|
+
lastActivity: string;
|
|
131
|
+
variables: Record<string, unknown>;
|
|
132
|
+
messageHistory: Array<{
|
|
133
|
+
role: 'user' | 'assistant' | 'system' | 'tool';
|
|
134
|
+
content: string;
|
|
135
|
+
timestamp: string;
|
|
136
|
+
}>;
|
|
137
|
+
}
|
|
138
|
+
interface ToolExecutionRecord {
|
|
139
|
+
id: string;
|
|
140
|
+
toolId: string;
|
|
141
|
+
params: Record<string, unknown>;
|
|
142
|
+
result: unknown;
|
|
143
|
+
error?: string;
|
|
144
|
+
timestamp: string;
|
|
145
|
+
duration: number;
|
|
146
|
+
edgeNodeId?: string;
|
|
147
|
+
}
|
|
148
|
+
interface ContextOptions {
|
|
149
|
+
/** Maximum number of memories to cache locally */
|
|
150
|
+
maxLocalMemories?: number;
|
|
151
|
+
/** Maximum message history per session */
|
|
152
|
+
maxMessageHistory?: number;
|
|
153
|
+
/** Maximum execution history to keep */
|
|
154
|
+
maxExecutionHistory?: number;
|
|
155
|
+
/** Session TTL in milliseconds */
|
|
156
|
+
sessionTtl?: number;
|
|
157
|
+
}
|
|
158
|
+
declare class RainfallDaemonContext {
|
|
159
|
+
private rainfall;
|
|
160
|
+
private options;
|
|
161
|
+
private localMemories;
|
|
162
|
+
private sessions;
|
|
163
|
+
private executionHistory;
|
|
164
|
+
private currentSessionId?;
|
|
165
|
+
constructor(rainfall: Rainfall, options?: ContextOptions);
|
|
166
|
+
/**
|
|
167
|
+
* Initialize the context - load recent memories from cloud
|
|
168
|
+
*/
|
|
169
|
+
initialize(): Promise<void>;
|
|
170
|
+
/**
|
|
171
|
+
* Create or get a session
|
|
172
|
+
*/
|
|
173
|
+
getSession(sessionId?: string): SessionContext;
|
|
174
|
+
/**
|
|
175
|
+
* Get the current active session
|
|
176
|
+
*/
|
|
177
|
+
getCurrentSession(): SessionContext | undefined;
|
|
178
|
+
/**
|
|
179
|
+
* Set the current active session
|
|
180
|
+
*/
|
|
181
|
+
setCurrentSession(sessionId: string): void;
|
|
182
|
+
/**
|
|
183
|
+
* Add a message to the current session history
|
|
184
|
+
*/
|
|
185
|
+
addMessage(role: 'user' | 'assistant' | 'system' | 'tool', content: string): void;
|
|
186
|
+
/**
|
|
187
|
+
* Store a memory (local + cloud sync)
|
|
188
|
+
*/
|
|
189
|
+
storeMemory(content: string, options?: {
|
|
190
|
+
keywords?: string[];
|
|
191
|
+
source?: string;
|
|
192
|
+
metadata?: Record<string, unknown>;
|
|
193
|
+
}): Promise<string>;
|
|
194
|
+
/**
|
|
195
|
+
* Recall memories by query
|
|
196
|
+
*/
|
|
197
|
+
recallMemories(query: string, topK?: number): Promise<MemoryEntry[]>;
|
|
198
|
+
/**
|
|
199
|
+
* Set a session variable
|
|
200
|
+
*/
|
|
201
|
+
setVariable(key: string, value: unknown): void;
|
|
202
|
+
/**
|
|
203
|
+
* Get a session variable
|
|
204
|
+
*/
|
|
205
|
+
getVariable<T = unknown>(key: string): T | undefined;
|
|
206
|
+
/**
|
|
207
|
+
* Record a tool execution
|
|
208
|
+
*/
|
|
209
|
+
recordExecution(toolId: string, params: Record<string, unknown>, result: unknown, options?: {
|
|
210
|
+
error?: string;
|
|
211
|
+
duration: number;
|
|
212
|
+
edgeNodeId?: string;
|
|
213
|
+
}): void;
|
|
214
|
+
/**
|
|
215
|
+
* Get recent execution history
|
|
216
|
+
*/
|
|
217
|
+
getExecutionHistory(limit?: number): ToolExecutionRecord[];
|
|
218
|
+
/**
|
|
219
|
+
* Get execution statistics
|
|
220
|
+
*/
|
|
221
|
+
getExecutionStats(): {
|
|
222
|
+
total: number;
|
|
223
|
+
successful: number;
|
|
224
|
+
failed: number;
|
|
225
|
+
averageDuration: number;
|
|
226
|
+
byTool: Record<string, number>;
|
|
227
|
+
};
|
|
228
|
+
/**
|
|
229
|
+
* Clear old sessions based on TTL
|
|
230
|
+
*/
|
|
231
|
+
cleanupSessions(): void;
|
|
232
|
+
/**
|
|
233
|
+
* Get context summary for debugging
|
|
234
|
+
*/
|
|
235
|
+
getStatus(): {
|
|
236
|
+
memoriesCached: number;
|
|
237
|
+
activeSessions: number;
|
|
238
|
+
currentSession?: string;
|
|
239
|
+
executionHistorySize: number;
|
|
240
|
+
};
|
|
241
|
+
private trimLocalMemories;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Rainfall Daemon Passive Listeners - File watchers, cron triggers, etc.
|
|
246
|
+
*
|
|
247
|
+
* Provides:
|
|
248
|
+
* - File system watchers for triggering workflows
|
|
249
|
+
* - Cron-style scheduled triggers
|
|
250
|
+
* - Webhook listeners (future)
|
|
251
|
+
* - Event bus for inter-node communication
|
|
252
|
+
*/
|
|
253
|
+
|
|
254
|
+
interface FileWatcherConfig {
|
|
255
|
+
id: string;
|
|
256
|
+
name: string;
|
|
257
|
+
watchPath: string;
|
|
258
|
+
pattern?: string;
|
|
259
|
+
events: ('create' | 'modify' | 'delete')[];
|
|
260
|
+
workflow: {
|
|
261
|
+
toolId: string;
|
|
262
|
+
params: Record<string, unknown>;
|
|
263
|
+
}[];
|
|
264
|
+
options?: {
|
|
265
|
+
recursive?: boolean;
|
|
266
|
+
ignoreInitial?: boolean;
|
|
267
|
+
debounceMs?: number;
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
interface CronTriggerConfig {
|
|
271
|
+
id: string;
|
|
272
|
+
name: string;
|
|
273
|
+
cron: string;
|
|
274
|
+
timezone?: string;
|
|
275
|
+
workflow: {
|
|
276
|
+
toolId: string;
|
|
277
|
+
params: Record<string, unknown>;
|
|
278
|
+
}[];
|
|
279
|
+
}
|
|
280
|
+
interface ListenerEvent {
|
|
281
|
+
id: string;
|
|
282
|
+
type: 'file' | 'cron' | 'webhook' | 'manual';
|
|
283
|
+
source: string;
|
|
284
|
+
timestamp: string;
|
|
285
|
+
data: Record<string, unknown>;
|
|
286
|
+
}
|
|
287
|
+
interface ListenerRegistry {
|
|
288
|
+
fileWatchers: FileWatcherConfig[];
|
|
289
|
+
cronTriggers: CronTriggerConfig[];
|
|
290
|
+
}
|
|
291
|
+
declare class RainfallListenerRegistry {
|
|
292
|
+
private rainfall;
|
|
293
|
+
private context;
|
|
294
|
+
private executor;
|
|
295
|
+
private watchers;
|
|
296
|
+
private cronIntervals;
|
|
297
|
+
private eventHistory;
|
|
298
|
+
private maxEventHistory;
|
|
299
|
+
constructor(rainfall: Rainfall, context: RainfallDaemonContext, executor: RainfallNetworkedExecutor);
|
|
300
|
+
/**
|
|
301
|
+
* Register a file watcher
|
|
302
|
+
* Note: Actual file watching requires fs.watch or chokidar
|
|
303
|
+
* This is the registry - actual watching is done by the daemon
|
|
304
|
+
*/
|
|
305
|
+
registerFileWatcher(config: FileWatcherConfig): Promise<void>;
|
|
306
|
+
/**
|
|
307
|
+
* Unregister a file watcher
|
|
308
|
+
*/
|
|
309
|
+
unregisterFileWatcher(id: string): Promise<void>;
|
|
310
|
+
/**
|
|
311
|
+
* Register a cron trigger
|
|
312
|
+
*/
|
|
313
|
+
registerCronTrigger(config: CronTriggerConfig): Promise<void>;
|
|
314
|
+
/**
|
|
315
|
+
* Unregister a cron trigger
|
|
316
|
+
*/
|
|
317
|
+
unregisterCronTrigger(id: string): void;
|
|
318
|
+
/**
|
|
319
|
+
* Handle a file event
|
|
320
|
+
*/
|
|
321
|
+
handleFileEvent(watcherId: string, eventType: 'create' | 'modify' | 'delete', filePath: string): Promise<void>;
|
|
322
|
+
/**
|
|
323
|
+
* Handle a cron tick
|
|
324
|
+
*/
|
|
325
|
+
private handleCronTick;
|
|
326
|
+
/**
|
|
327
|
+
* Trigger a manual event (for testing or programmatic triggers)
|
|
328
|
+
*/
|
|
329
|
+
triggerManual(name: string, data?: Record<string, unknown>): Promise<void>;
|
|
330
|
+
/**
|
|
331
|
+
* Get recent events
|
|
332
|
+
*/
|
|
333
|
+
getRecentEvents(limit?: number): ListenerEvent[];
|
|
334
|
+
/**
|
|
335
|
+
* Get active listeners status
|
|
336
|
+
*/
|
|
337
|
+
getStatus(): {
|
|
338
|
+
fileWatchers: number;
|
|
339
|
+
cronTriggers: number;
|
|
340
|
+
recentEvents: number;
|
|
341
|
+
};
|
|
342
|
+
/**
|
|
343
|
+
* Stop all listeners
|
|
344
|
+
*/
|
|
345
|
+
stopAll(): Promise<void>;
|
|
346
|
+
private recordEvent;
|
|
347
|
+
/**
|
|
348
|
+
* Simple cron parser - converts basic cron expressions to milliseconds
|
|
349
|
+
* Supports: @hourly, @daily, @weekly, and simple intervals like every N minutes
|
|
350
|
+
*/
|
|
351
|
+
private parseCronToMs;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Create a file watcher workflow helper
|
|
355
|
+
*/
|
|
356
|
+
declare function createFileWatcherWorkflow(name: string, watchPath: string, options: {
|
|
357
|
+
pattern?: string;
|
|
358
|
+
events?: ('create' | 'modify' | 'delete')[];
|
|
359
|
+
workflow: {
|
|
360
|
+
toolId: string;
|
|
361
|
+
params: Record<string, unknown>;
|
|
362
|
+
}[];
|
|
363
|
+
}): FileWatcherConfig;
|
|
364
|
+
/**
|
|
365
|
+
* Create a cron trigger workflow helper
|
|
366
|
+
*/
|
|
367
|
+
declare function createCronWorkflow(name: string, cron: string, workflow: {
|
|
368
|
+
toolId: string;
|
|
369
|
+
params: Record<string, unknown>;
|
|
370
|
+
}[]): CronTriggerConfig;
|
|
371
|
+
|
|
372
|
+
export { type ContextOptions as C, type EdgeNodeRegistration as E, type FileWatcherConfig as F, type ListenerEvent as L, type MemoryEntry as M, type NetworkedExecutorOptions as N, type QueuedJob as Q, RainfallNetworkedExecutor as R, type SessionContext as S, type ToolExecutionRecord as T, RainfallDaemonContext as a, RainfallListenerRegistry as b, type CronTriggerConfig as c, type ListenerRegistry as d, type NodeCapabilities as e, createCronWorkflow as f, createFileWatcherWorkflow as g };
|