@ebowwa/stack 0.2.0 → 0.3.0
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 +63317 -3272
- package/package.json +7 -4
- package/src/index.ts +84 -18
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ebowwa/stack",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Cross-channel AI stack with
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Cross-channel AI stack with node-agent integration (SSH + Telegram + Ralph/Git)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -25,7 +25,9 @@
|
|
|
25
25
|
"ssh",
|
|
26
26
|
"ai",
|
|
27
27
|
"cross-channel",
|
|
28
|
-
"memory"
|
|
28
|
+
"memory",
|
|
29
|
+
"ralph",
|
|
30
|
+
"node-agent"
|
|
29
31
|
],
|
|
30
32
|
"author": "Ebowwa Labs <labs@ebowwa.com>",
|
|
31
33
|
"license": "MIT",
|
|
@@ -40,7 +42,8 @@
|
|
|
40
42
|
"@ebowwa/channel-ssh": "^2.1.1",
|
|
41
43
|
"@ebowwa/channel-telegram": "^1.14.2",
|
|
42
44
|
"@ebowwa/channel-types": "^0.2.1",
|
|
43
|
-
"@ebowwa/codespaces-types": "^1.6.1"
|
|
45
|
+
"@ebowwa/codespaces-types": "^1.6.1",
|
|
46
|
+
"@ebowwa/node-agent": "^0.6.5"
|
|
44
47
|
},
|
|
45
48
|
"devDependencies": {
|
|
46
49
|
"@types/bun": "latest"
|
package/src/index.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
/**
|
|
3
|
-
* @ebowwa/stack - Cross-Channel AI Stack
|
|
3
|
+
* @ebowwa/stack - Cross-Channel AI Stack with Node Agent
|
|
4
4
|
*
|
|
5
5
|
* Features:
|
|
6
6
|
* - Unified Router: Cross-channel communication (SSH + Telegram)
|
|
7
7
|
* - Cross-channel memory with permission controls
|
|
8
8
|
* - AI-powered message handling
|
|
9
|
+
* - Node Agent: Ralph loops, Git, Monitoring (imported but disabled for now)
|
|
9
10
|
*
|
|
10
11
|
* Architecture:
|
|
11
12
|
* ┌──────────────────────────────────────────────────────────────┐
|
|
@@ -22,9 +23,13 @@
|
|
|
22
23
|
* │ │ (Cross-Context) │ │
|
|
23
24
|
* │ └─────────┬─────────┘ │
|
|
24
25
|
* │ │ │
|
|
25
|
-
* │
|
|
26
|
-
* │
|
|
27
|
-
* │
|
|
26
|
+
* │ ┌───────────────────┴───────────────────┐ │
|
|
27
|
+
* │ │ │ │
|
|
28
|
+
* │ ┌───────▼───────┐ ┌──────────▼───────┐ │
|
|
29
|
+
* │ │ AI Brain │ │ Node Agent │ │
|
|
30
|
+
* │ │ (GLM) │ │ (Ralph/Git/...) │ │
|
|
31
|
+
* │ └───────────────┘ │ [DISABLED] │ │
|
|
32
|
+
* │ └──────────────────┘ │
|
|
28
33
|
* └──────────────────────────────────────────────────────────────┘
|
|
29
34
|
*/
|
|
30
35
|
|
|
@@ -33,6 +38,15 @@ import type { ChannelConnector, ChannelMessage, ChannelResponse, ChannelId } fro
|
|
|
33
38
|
import { GLMClient } from "@ebowwa/ai";
|
|
34
39
|
import { ToolExecutor, BUILTIN_TOOLS } from "@ebowwa/ai/tools";
|
|
35
40
|
|
|
41
|
+
// Node Agent imports (services available but disabled)
|
|
42
|
+
import {
|
|
43
|
+
RalphService,
|
|
44
|
+
GitService,
|
|
45
|
+
ConsoleLoggerService,
|
|
46
|
+
initializeStateService,
|
|
47
|
+
getState,
|
|
48
|
+
} from "@ebowwa/node-agent/lib";
|
|
49
|
+
|
|
36
50
|
// ============================================================
|
|
37
51
|
// Types
|
|
38
52
|
// ============================================================
|
|
@@ -64,6 +78,8 @@ export interface StackConfig {
|
|
|
64
78
|
name: string;
|
|
65
79
|
hostname?: string;
|
|
66
80
|
};
|
|
81
|
+
/** Enable Node Agent features (Ralph, Git, etc.) */
|
|
82
|
+
enableNodeAgent?: boolean;
|
|
67
83
|
}
|
|
68
84
|
|
|
69
85
|
export interface StackState {
|
|
@@ -76,6 +92,9 @@ export interface StackState {
|
|
|
76
92
|
enabled: boolean;
|
|
77
93
|
port?: number;
|
|
78
94
|
};
|
|
95
|
+
nodeAgent: {
|
|
96
|
+
enabled: boolean;
|
|
97
|
+
};
|
|
79
98
|
}
|
|
80
99
|
|
|
81
100
|
// ============================================================
|
|
@@ -92,6 +111,11 @@ export class Stack {
|
|
|
92
111
|
private channels: Map<string, ChannelConnector> = new Map();
|
|
93
112
|
private abortController: AbortController | null = null;
|
|
94
113
|
|
|
114
|
+
// Node Agent services (initialized but may not be used)
|
|
115
|
+
private ralphService: RalphService | null = null;
|
|
116
|
+
private gitService: GitService | null = null;
|
|
117
|
+
private consoleLogger: ConsoleLoggerService | null = null;
|
|
118
|
+
|
|
95
119
|
constructor(config: StackConfig) {
|
|
96
120
|
this.config = {
|
|
97
121
|
...config,
|
|
@@ -104,9 +128,10 @@ export class Stack {
|
|
|
104
128
|
started: new Date(),
|
|
105
129
|
channels: { ssh: false, telegram: false },
|
|
106
130
|
api: { enabled: !!this.config.api, port: this.config.api?.port },
|
|
131
|
+
nodeAgent: { enabled: false },
|
|
107
132
|
};
|
|
108
133
|
|
|
109
|
-
// Build memory channels dynamically
|
|
134
|
+
// Build memory channels dynamically
|
|
110
135
|
const memoryChannels: Record<string, { memoryFile: string; maxMessages: number }> = {};
|
|
111
136
|
const permissions: Record<string, { canRead: string[] }> = {};
|
|
112
137
|
const enabledChannels: string[] = [];
|
|
@@ -120,30 +145,31 @@ export class Stack {
|
|
|
120
145
|
enabledChannels.push("telegram");
|
|
121
146
|
}
|
|
122
147
|
|
|
123
|
-
// Set up cross-channel permissions
|
|
124
148
|
for (const channel of enabledChannels) {
|
|
125
149
|
permissions[channel] = { canRead: enabledChannels.filter(c => c !== channel) };
|
|
126
150
|
}
|
|
127
151
|
|
|
128
|
-
// Initialize shared memory
|
|
129
152
|
this.memory = createPermissionMemory({
|
|
130
153
|
channels: memoryChannels,
|
|
131
154
|
permissions,
|
|
132
155
|
});
|
|
133
156
|
|
|
134
|
-
// Initialize router
|
|
135
157
|
this.router = createChannelRouter({
|
|
136
158
|
announcement: {
|
|
137
159
|
serverName: this.config.node.name,
|
|
138
160
|
hostname: this.config.node.hostname,
|
|
139
161
|
packageName: "@ebowwa/stack",
|
|
140
|
-
version: "0.
|
|
162
|
+
version: "0.3.0",
|
|
141
163
|
},
|
|
142
164
|
});
|
|
143
165
|
|
|
144
|
-
// Initialize AI
|
|
145
166
|
this.client = new GLMClient();
|
|
146
167
|
this.executor = new ToolExecutor(this.client, [...BUILTIN_TOOLS]);
|
|
168
|
+
|
|
169
|
+
// Initialize Node Agent services (but don't enable features yet)
|
|
170
|
+
this.ralphService = new RalphService();
|
|
171
|
+
this.gitService = new GitService();
|
|
172
|
+
this.consoleLogger = new ConsoleLoggerService();
|
|
147
173
|
}
|
|
148
174
|
|
|
149
175
|
// ============================================================
|
|
@@ -183,6 +209,30 @@ export class Stack {
|
|
|
183
209
|
console.log("[Stack] Telegram registered");
|
|
184
210
|
}
|
|
185
211
|
|
|
212
|
+
// ============================================================
|
|
213
|
+
// Node Agent Initialization
|
|
214
|
+
// ============================================================
|
|
215
|
+
|
|
216
|
+
private async initializeNodeAgent(): Promise<void> {
|
|
217
|
+
console.log("[Stack] Initializing Node Agent services...");
|
|
218
|
+
|
|
219
|
+
// Initialize state service
|
|
220
|
+
try {
|
|
221
|
+
await initializeStateService();
|
|
222
|
+
console.log("[Stack] State service initialized");
|
|
223
|
+
} catch (error) {
|
|
224
|
+
console.warn("[Stack] State service initialization failed (non-critical):", error);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Ralph and Git services are instantiated but features are DISABLED
|
|
228
|
+
// TODO: Enable when ready
|
|
229
|
+
// this.ralphService?.startMonitoring();
|
|
230
|
+
// this.gitService?.initialize();
|
|
231
|
+
|
|
232
|
+
this.state.nodeAgent.enabled = true;
|
|
233
|
+
console.log("[Stack] Node Agent services ready (Ralph/Git DISABLED)");
|
|
234
|
+
}
|
|
235
|
+
|
|
186
236
|
// ============================================================
|
|
187
237
|
// Message Handler
|
|
188
238
|
// ============================================================
|
|
@@ -194,7 +244,7 @@ export class Stack {
|
|
|
194
244
|
|
|
195
245
|
console.log(`[${channel}] ${text.slice(0, 50)}...`);
|
|
196
246
|
|
|
197
|
-
//
|
|
247
|
+
// Typing indicator for Telegram
|
|
198
248
|
const telegramChannel = this.channels.get("telegram") as { startTypingIndicator?: (chatId: string) => void; stopTypingIndicator?: (chatId: string) => void } | undefined;
|
|
199
249
|
const chatId = channelId.metadata?.chatId as string | undefined;
|
|
200
250
|
if (channel === "telegram" && telegramChannel?.startTypingIndicator && chatId) {
|
|
@@ -207,7 +257,7 @@ export class Stack {
|
|
|
207
257
|
}
|
|
208
258
|
};
|
|
209
259
|
|
|
210
|
-
//
|
|
260
|
+
// Memory commands
|
|
211
261
|
const cmdResult = parseMemoryCommand(this.memory, channel, text);
|
|
212
262
|
if (cmdResult.handled) {
|
|
213
263
|
stopTyping();
|
|
@@ -217,7 +267,7 @@ export class Stack {
|
|
|
217
267
|
};
|
|
218
268
|
}
|
|
219
269
|
|
|
220
|
-
//
|
|
270
|
+
// Status command
|
|
221
271
|
if (text.trim().toLowerCase() === "/status") {
|
|
222
272
|
stopTyping();
|
|
223
273
|
return {
|
|
@@ -226,10 +276,19 @@ export class Stack {
|
|
|
226
276
|
};
|
|
227
277
|
}
|
|
228
278
|
|
|
229
|
-
//
|
|
279
|
+
// Ralph commands (DISABLED for now)
|
|
280
|
+
// if (text.startsWith("/ralph")) {
|
|
281
|
+
// stopTyping();
|
|
282
|
+
// return {
|
|
283
|
+
// content: { text: await this.handleRalphCommand(text) },
|
|
284
|
+
// replyTo: { messageId: message.messageId, channelId: message.channelId },
|
|
285
|
+
// };
|
|
286
|
+
// }
|
|
287
|
+
|
|
288
|
+
// Add to memory
|
|
230
289
|
this.memory.addMessage(channel, { role: "user", content: text });
|
|
231
290
|
|
|
232
|
-
// Build messages
|
|
291
|
+
// Build LLM messages
|
|
233
292
|
const llmMessages = this.memory.buildLLMMessages(
|
|
234
293
|
channel,
|
|
235
294
|
this.buildSystemPrompt(),
|
|
@@ -283,6 +342,7 @@ export class Stack {
|
|
|
283
342
|
## Info
|
|
284
343
|
- Node: ${this.config.node.name}
|
|
285
344
|
- Channels: ${channelList}
|
|
345
|
+
- Node Agent: ${this.state.nodeAgent.enabled ? "ready (Ralph/Git disabled)" : "off"}
|
|
286
346
|
- API: :${this.config.api?.port ?? 8911}`;
|
|
287
347
|
}
|
|
288
348
|
|
|
@@ -290,13 +350,14 @@ export class Stack {
|
|
|
290
350
|
const lines = [
|
|
291
351
|
`**${this.config.node.name} Status**`,
|
|
292
352
|
`Channels: SSH=${this.state.channels.ssh}, Telegram=${this.state.channels.telegram}`,
|
|
353
|
+
`Node Agent: ${this.state.nodeAgent.enabled ? "ready (Ralph/Git disabled)" : "off"}`,
|
|
293
354
|
`Uptime: ${Math.floor((Date.now() - this.state.started.getTime()) / 1000)}s`,
|
|
294
355
|
];
|
|
295
356
|
return lines.join("\n");
|
|
296
357
|
}
|
|
297
358
|
|
|
298
359
|
// ============================================================
|
|
299
|
-
// HTTP API
|
|
360
|
+
// HTTP API
|
|
300
361
|
// ============================================================
|
|
301
362
|
|
|
302
363
|
private startAPI(): void {
|
|
@@ -322,16 +383,15 @@ export class Stack {
|
|
|
322
383
|
return new Response(null, { headers: corsHeaders });
|
|
323
384
|
}
|
|
324
385
|
|
|
325
|
-
// GET /api/status
|
|
326
386
|
if (path === "/api/status" && req.method === "GET") {
|
|
327
387
|
return Response.json({
|
|
328
388
|
node: this.config.node.name,
|
|
329
389
|
channels: this.state.channels,
|
|
390
|
+
nodeAgent: this.state.nodeAgent,
|
|
330
391
|
uptime: Math.floor((Date.now() - this.state.started.getTime()) / 1000),
|
|
331
392
|
}, { headers: corsHeaders });
|
|
332
393
|
}
|
|
333
394
|
|
|
334
|
-
// GET /health
|
|
335
395
|
if (path === "/health") {
|
|
336
396
|
return Response.json({ status: "ok" }, { headers: corsHeaders });
|
|
337
397
|
}
|
|
@@ -352,6 +412,10 @@ export class Stack {
|
|
|
352
412
|
|
|
353
413
|
this.abortController = new AbortController();
|
|
354
414
|
|
|
415
|
+
// Initialize Node Agent (services ready but features disabled)
|
|
416
|
+
await this.initializeNodeAgent();
|
|
417
|
+
|
|
418
|
+
// Register channels
|
|
355
419
|
await this.registerSSH();
|
|
356
420
|
await this.registerTelegram();
|
|
357
421
|
|
|
@@ -370,6 +434,7 @@ export class Stack {
|
|
|
370
434
|
if (this.state.api.enabled) {
|
|
371
435
|
console.log(` - API: :${this.state.api.port}`);
|
|
372
436
|
}
|
|
437
|
+
console.log(" - Node Agent: ready (Ralph/Git disabled)");
|
|
373
438
|
console.log(" - Commands: /status, /memory <cmd>");
|
|
374
439
|
|
|
375
440
|
await new Promise(() => {});
|
|
@@ -415,6 +480,7 @@ async function main() {
|
|
|
415
480
|
name: process.env.NODE_NAME || "stack",
|
|
416
481
|
hostname: process.env.HOSTNAME || "localhost",
|
|
417
482
|
},
|
|
483
|
+
enableNodeAgent: process.env.ENABLE_NODE_AGENT !== "false",
|
|
418
484
|
};
|
|
419
485
|
|
|
420
486
|
const stack = new Stack(config);
|