@framers/agentos 0.1.26 → 0.1.28
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/api/AgentOSOrchestrator.js +1 -1
- package/dist/api/AgentOSOrchestrator.js.map +1 -1
- package/dist/channels/ChannelRouter.d.ts.map +1 -1
- package/dist/channels/ChannelRouter.js +1 -1
- package/dist/channels/ChannelRouter.js.map +1 -1
- package/dist/channels/IChannelAdapter.d.ts.map +1 -1
- package/dist/channels/adapters/BaseChannelAdapter.d.ts +130 -0
- package/dist/channels/adapters/BaseChannelAdapter.d.ts.map +1 -0
- package/dist/channels/adapters/BaseChannelAdapter.js +257 -0
- package/dist/channels/adapters/BaseChannelAdapter.js.map +1 -0
- package/dist/channels/adapters/DiscordChannelAdapter.d.ts +86 -0
- package/dist/channels/adapters/DiscordChannelAdapter.d.ts.map +1 -0
- package/dist/channels/adapters/DiscordChannelAdapter.js +550 -0
- package/dist/channels/adapters/DiscordChannelAdapter.js.map +1 -0
- package/dist/channels/adapters/GoogleChatChannelAdapter.d.ts +117 -0
- package/dist/channels/adapters/GoogleChatChannelAdapter.d.ts.map +1 -0
- package/dist/channels/adapters/GoogleChatChannelAdapter.js +632 -0
- package/dist/channels/adapters/GoogleChatChannelAdapter.js.map +1 -0
- package/dist/channels/adapters/IRCChannelAdapter.d.ts +86 -0
- package/dist/channels/adapters/IRCChannelAdapter.d.ts.map +1 -0
- package/dist/channels/adapters/IRCChannelAdapter.js +253 -0
- package/dist/channels/adapters/IRCChannelAdapter.js.map +1 -0
- package/dist/channels/adapters/RedditChannelAdapter.d.ts +123 -0
- package/dist/channels/adapters/RedditChannelAdapter.d.ts.map +1 -0
- package/dist/channels/adapters/RedditChannelAdapter.js +516 -0
- package/dist/channels/adapters/RedditChannelAdapter.js.map +1 -0
- package/dist/channels/adapters/SignalChannelAdapter.d.ts +120 -0
- package/dist/channels/adapters/SignalChannelAdapter.d.ts.map +1 -0
- package/dist/channels/adapters/SignalChannelAdapter.js +521 -0
- package/dist/channels/adapters/SignalChannelAdapter.js.map +1 -0
- package/dist/channels/adapters/SlackChannelAdapter.d.ts +96 -0
- package/dist/channels/adapters/SlackChannelAdapter.d.ts.map +1 -0
- package/dist/channels/adapters/SlackChannelAdapter.js +535 -0
- package/dist/channels/adapters/SlackChannelAdapter.js.map +1 -0
- package/dist/channels/adapters/TeamsChannelAdapter.d.ts +138 -0
- package/dist/channels/adapters/TeamsChannelAdapter.d.ts.map +1 -0
- package/dist/channels/adapters/TeamsChannelAdapter.js +639 -0
- package/dist/channels/adapters/TeamsChannelAdapter.js.map +1 -0
- package/dist/channels/adapters/TelegramChannelAdapter.d.ts +83 -0
- package/dist/channels/adapters/TelegramChannelAdapter.d.ts.map +1 -0
- package/dist/channels/adapters/TelegramChannelAdapter.js +463 -0
- package/dist/channels/adapters/TelegramChannelAdapter.js.map +1 -0
- package/dist/channels/adapters/TwitterChannelAdapter.d.ts +117 -0
- package/dist/channels/adapters/TwitterChannelAdapter.d.ts.map +1 -0
- package/dist/channels/adapters/TwitterChannelAdapter.js +489 -0
- package/dist/channels/adapters/TwitterChannelAdapter.js.map +1 -0
- package/dist/channels/adapters/WebChatChannelAdapter.d.ts +141 -0
- package/dist/channels/adapters/WebChatChannelAdapter.d.ts.map +1 -0
- package/dist/channels/adapters/WebChatChannelAdapter.js +539 -0
- package/dist/channels/adapters/WebChatChannelAdapter.js.map +1 -0
- package/dist/channels/adapters/WhatsAppChannelAdapter.d.ts +122 -0
- package/dist/channels/adapters/WhatsAppChannelAdapter.d.ts.map +1 -0
- package/dist/channels/adapters/WhatsAppChannelAdapter.js +643 -0
- package/dist/channels/adapters/WhatsAppChannelAdapter.js.map +1 -0
- package/dist/channels/adapters/index.d.ts +34 -0
- package/dist/channels/adapters/index.d.ts.map +1 -0
- package/dist/channels/adapters/index.js +25 -0
- package/dist/channels/adapters/index.js.map +1 -0
- package/dist/channels/index.d.ts +24 -0
- package/dist/channels/index.d.ts.map +1 -1
- package/dist/channels/index.js +16 -0
- package/dist/channels/index.js.map +1 -1
- package/dist/cognitive_substrate/personas/metaprompt_presets.d.ts.map +1 -1
- package/dist/cognitive_substrate/personas/metaprompt_presets.js +0 -2
- package/dist/cognitive_substrate/personas/metaprompt_presets.js.map +1 -1
- package/dist/core/provenance/crypto/HashChain.d.ts.map +1 -1
- package/dist/core/provenance/enforcement/AutonomyGuard.d.ts.map +1 -1
- package/dist/core/provenance/enforcement/ProvenanceStorageHooks.d.ts.map +1 -1
- package/dist/core/provenance/enforcement/ProvenanceStorageHooks.js +2 -1
- package/dist/core/provenance/enforcement/ProvenanceStorageHooks.js.map +1 -1
- package/dist/core/provenance/ledger/EventTypes.d.ts.map +1 -1
- package/dist/core/safety/ToolExecutionGuard.d.ts.map +1 -1
- package/dist/core/safety/ToolExecutionGuard.js +0 -1
- package/dist/core/safety/ToolExecutionGuard.js.map +1 -1
- package/dist/extensions/ExtensionManager.d.ts.map +1 -1
- package/dist/extensions/ExtensionManager.js +3 -9
- package/dist/extensions/ExtensionManager.js.map +1 -1
- package/dist/rag/RetrievalAugmentor.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,521 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Signal Channel Adapter for AgentOS.
|
|
3
|
+
*
|
|
4
|
+
* Integrates with the Signal messaging protocol via `signal-cli`, a
|
|
5
|
+
* command-line tool for Signal. The adapter invokes signal-cli as a
|
|
6
|
+
* subprocess for sending/receiving messages, providing end-to-end
|
|
7
|
+
* encrypted communication for agents.
|
|
8
|
+
*
|
|
9
|
+
* **Dependencies**: Requires `signal-cli` to be installed and
|
|
10
|
+
* configured on the system (either registered or linked to an
|
|
11
|
+
* existing device). See https://github.com/AsamK/signal-cli
|
|
12
|
+
*
|
|
13
|
+
* The adapter supports two operation modes:
|
|
14
|
+
* 1. **Subprocess mode** (default): Invokes signal-cli per command.
|
|
15
|
+
* 2. **JSON-RPC daemon mode**: Connects to a running signal-cli
|
|
16
|
+
* daemon for lower latency. Enabled when `daemonSocket` param
|
|
17
|
+
* is provided.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* const signal = new SignalChannelAdapter();
|
|
22
|
+
* await signal.initialize({
|
|
23
|
+
* platform: 'signal',
|
|
24
|
+
* credential: '+1234567890', // registered phone number
|
|
25
|
+
* params: {
|
|
26
|
+
* signalCliPath: '/usr/local/bin/signal-cli',
|
|
27
|
+
* configDir: '/home/agent/.local/share/signal-cli',
|
|
28
|
+
* },
|
|
29
|
+
* });
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @module @framers/agentos/channels/adapters/SignalChannelAdapter
|
|
33
|
+
*/
|
|
34
|
+
import { BaseChannelAdapter } from './BaseChannelAdapter.js';
|
|
35
|
+
// ============================================================================
|
|
36
|
+
// SignalChannelAdapter
|
|
37
|
+
// ============================================================================
|
|
38
|
+
/**
|
|
39
|
+
* Channel adapter for the Signal messaging protocol via signal-cli.
|
|
40
|
+
*
|
|
41
|
+
* Capabilities: `text`, `images`, `audio`, `voice_notes`,
|
|
42
|
+
* `documents`, `reactions`, `group_chat`.
|
|
43
|
+
*
|
|
44
|
+
* Conversation ID mapping:
|
|
45
|
+
* - Direct message: phone number (e.g., '+1234567890')
|
|
46
|
+
* - Group: group ID in base64 format, prefixed with 'group:'
|
|
47
|
+
*/
|
|
48
|
+
export class SignalChannelAdapter extends BaseChannelAdapter {
|
|
49
|
+
constructor() {
|
|
50
|
+
super(...arguments);
|
|
51
|
+
this.platform = 'signal';
|
|
52
|
+
this.displayName = 'Signal';
|
|
53
|
+
this.capabilities = [
|
|
54
|
+
'text',
|
|
55
|
+
'images',
|
|
56
|
+
'audio',
|
|
57
|
+
'voice_notes',
|
|
58
|
+
'documents',
|
|
59
|
+
'reactions',
|
|
60
|
+
'group_chat',
|
|
61
|
+
];
|
|
62
|
+
/** Path to signal-cli binary. */
|
|
63
|
+
this.signalCliPath = 'signal-cli';
|
|
64
|
+
/** Trust mode for unknown identities. */
|
|
65
|
+
this.trustMode = 'on-first-use';
|
|
66
|
+
}
|
|
67
|
+
// ── Abstract hook implementations ──
|
|
68
|
+
async doConnect(auth) {
|
|
69
|
+
const params = auth.params ?? {};
|
|
70
|
+
this.phoneNumber = auth.credential;
|
|
71
|
+
if (!this.phoneNumber) {
|
|
72
|
+
throw new Error('Signal credential (phone number) is required.');
|
|
73
|
+
}
|
|
74
|
+
// Validate phone number format (basic check)
|
|
75
|
+
if (!this.phoneNumber.startsWith('+')) {
|
|
76
|
+
throw new Error('Signal phone number must be in international format starting with "+" (e.g., +1234567890).');
|
|
77
|
+
}
|
|
78
|
+
this.signalCliPath = params.signalCliPath ?? 'signal-cli';
|
|
79
|
+
this.configDir = params.configDir;
|
|
80
|
+
this.trustMode = params.trustMode ?? 'on-first-use';
|
|
81
|
+
this.daemonSocket = params.daemonSocket;
|
|
82
|
+
// Verify signal-cli is available
|
|
83
|
+
await this.verifySignalCli();
|
|
84
|
+
// Verify the account is registered / linked
|
|
85
|
+
await this.verifyAccount();
|
|
86
|
+
// Set up message receiving
|
|
87
|
+
if (this.daemonSocket) {
|
|
88
|
+
await this.connectDaemon();
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
this.startReceivePolling();
|
|
92
|
+
}
|
|
93
|
+
this.platformInfo = {
|
|
94
|
+
phoneNumber: this.phoneNumber,
|
|
95
|
+
signalCliPath: this.signalCliPath,
|
|
96
|
+
mode: this.daemonSocket ? 'daemon' : 'subprocess',
|
|
97
|
+
trustMode: this.trustMode,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
async doSendMessage(conversationId, content) {
|
|
101
|
+
const text = this.extractText(content.blocks);
|
|
102
|
+
const attachments = this.extractAttachmentPaths(content.blocks);
|
|
103
|
+
const isGroup = conversationId.startsWith('group:');
|
|
104
|
+
const target = isGroup ? conversationId.slice(6) : conversationId;
|
|
105
|
+
// Build signal-cli send command
|
|
106
|
+
const args = ['send'];
|
|
107
|
+
if (text) {
|
|
108
|
+
args.push('-m', text);
|
|
109
|
+
}
|
|
110
|
+
// Add attachments
|
|
111
|
+
for (const attachment of attachments) {
|
|
112
|
+
args.push('-a', attachment);
|
|
113
|
+
}
|
|
114
|
+
if (isGroup) {
|
|
115
|
+
args.push('-g', target);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
args.push(target);
|
|
119
|
+
}
|
|
120
|
+
// Handle reply-to
|
|
121
|
+
if (content.replyToMessageId) {
|
|
122
|
+
// signal-cli supports --quote-timestamp and --quote-author for replies
|
|
123
|
+
const [quoteTimestamp, quoteAuthor] = content.replyToMessageId.split(':');
|
|
124
|
+
if (quoteTimestamp) {
|
|
125
|
+
args.push('--quote-timestamp', quoteTimestamp);
|
|
126
|
+
}
|
|
127
|
+
if (quoteAuthor) {
|
|
128
|
+
args.push('--quote-author', quoteAuthor);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
await this.execSignalCli(args);
|
|
132
|
+
const messageId = `signal-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
133
|
+
return {
|
|
134
|
+
messageId,
|
|
135
|
+
timestamp: new Date().toISOString(),
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
async doShutdown() {
|
|
139
|
+
// Stop polling
|
|
140
|
+
if (this.pollTimer) {
|
|
141
|
+
clearInterval(this.pollTimer);
|
|
142
|
+
this.pollTimer = undefined;
|
|
143
|
+
}
|
|
144
|
+
// Kill receive process
|
|
145
|
+
if (this.receiveProcess) {
|
|
146
|
+
try {
|
|
147
|
+
this.receiveProcess.kill('SIGTERM');
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
// Best effort
|
|
151
|
+
}
|
|
152
|
+
this.receiveProcess = undefined;
|
|
153
|
+
}
|
|
154
|
+
// Close daemon connection
|
|
155
|
+
if (this.daemonConnection) {
|
|
156
|
+
try {
|
|
157
|
+
this.daemonConnection.destroy?.();
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
// Best effort
|
|
161
|
+
}
|
|
162
|
+
this.daemonConnection = undefined;
|
|
163
|
+
}
|
|
164
|
+
this.phoneNumber = undefined;
|
|
165
|
+
this.configDir = undefined;
|
|
166
|
+
this.daemonSocket = undefined;
|
|
167
|
+
}
|
|
168
|
+
// ── Signal-specific public methods ──
|
|
169
|
+
/**
|
|
170
|
+
* Send a reaction to a message.
|
|
171
|
+
*
|
|
172
|
+
* @param conversationId - Target conversation (phone number or group:id).
|
|
173
|
+
* @param targetAuthor - Phone number of the message author being reacted to.
|
|
174
|
+
* @param targetTimestamp - Timestamp of the target message (Signal's message ID).
|
|
175
|
+
* @param emoji - The reaction emoji.
|
|
176
|
+
*/
|
|
177
|
+
async sendReaction(conversationId, targetAuthor, targetTimestamp, emoji) {
|
|
178
|
+
const isGroup = conversationId.startsWith('group:');
|
|
179
|
+
const target = isGroup ? conversationId.slice(6) : conversationId;
|
|
180
|
+
const args = [
|
|
181
|
+
'sendReaction',
|
|
182
|
+
'-a', targetAuthor,
|
|
183
|
+
'-t', targetTimestamp,
|
|
184
|
+
'-e', emoji,
|
|
185
|
+
];
|
|
186
|
+
if (isGroup) {
|
|
187
|
+
args.push('-g', target);
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
args.push(target);
|
|
191
|
+
}
|
|
192
|
+
await this.execSignalCli(args);
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* List groups the account is a member of.
|
|
196
|
+
*/
|
|
197
|
+
async listGroups() {
|
|
198
|
+
const output = await this.execSignalCli(['listGroups', '-d']);
|
|
199
|
+
try {
|
|
200
|
+
const groups = JSON.parse(output);
|
|
201
|
+
return Array.isArray(groups)
|
|
202
|
+
? groups.map((g) => ({
|
|
203
|
+
id: g.id ?? g.groupId ?? '',
|
|
204
|
+
name: g.name ?? '',
|
|
205
|
+
members: g.members ?? [],
|
|
206
|
+
}))
|
|
207
|
+
: [];
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
// Parse line-based output as fallback
|
|
211
|
+
return [];
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Mark messages as read (send read receipt).
|
|
216
|
+
*/
|
|
217
|
+
async markAsRead(senderNumber, timestamps) {
|
|
218
|
+
const args = ['sendReceipt', '-t'];
|
|
219
|
+
args.push(...timestamps);
|
|
220
|
+
args.push('--type', 'read');
|
|
221
|
+
args.push(senderNumber);
|
|
222
|
+
await this.execSignalCli(args);
|
|
223
|
+
}
|
|
224
|
+
// ── Private: signal-cli execution ──
|
|
225
|
+
async verifySignalCli() {
|
|
226
|
+
try {
|
|
227
|
+
const output = await this.execSignalCli(['--version']);
|
|
228
|
+
console.log(`[Signal] signal-cli version: ${output.trim()}`);
|
|
229
|
+
}
|
|
230
|
+
catch (err) {
|
|
231
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
232
|
+
throw new Error(`signal-cli not found or not executable at "${this.signalCliPath}". ` +
|
|
233
|
+
`Ensure it is installed: ${message}`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
async verifyAccount() {
|
|
237
|
+
try {
|
|
238
|
+
// List accounts to verify our number is registered
|
|
239
|
+
const output = await this.execSignalCli(['listAccounts']);
|
|
240
|
+
if (output && !output.includes(this.phoneNumber)) {
|
|
241
|
+
console.warn(`[Signal] Phone number ${this.phoneNumber} may not be registered. ` +
|
|
242
|
+
'Attempting to proceed anyway.');
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
catch {
|
|
246
|
+
// listAccounts may not be available in all signal-cli versions
|
|
247
|
+
// Proceed and let the first send/receive reveal issues
|
|
248
|
+
console.warn('[Signal] Could not verify account registration. Proceeding.');
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Execute a signal-cli command and return stdout.
|
|
253
|
+
*/
|
|
254
|
+
async execSignalCli(args) {
|
|
255
|
+
const { execFile } = await import('node:child_process');
|
|
256
|
+
const { promisify } = await import('node:util');
|
|
257
|
+
const execFileAsync = promisify(execFile);
|
|
258
|
+
const fullArgs = [];
|
|
259
|
+
// Add account flag
|
|
260
|
+
if (this.phoneNumber) {
|
|
261
|
+
fullArgs.push('-a', this.phoneNumber);
|
|
262
|
+
}
|
|
263
|
+
// Add config directory
|
|
264
|
+
if (this.configDir) {
|
|
265
|
+
fullArgs.push('--config', this.configDir);
|
|
266
|
+
}
|
|
267
|
+
// Add trust mode
|
|
268
|
+
if (this.trustMode === 'always') {
|
|
269
|
+
fullArgs.push('--trust-new-identities', 'always');
|
|
270
|
+
}
|
|
271
|
+
// Request JSON output where applicable
|
|
272
|
+
fullArgs.push('--output', 'json');
|
|
273
|
+
// Add the command args
|
|
274
|
+
fullArgs.push(...args);
|
|
275
|
+
try {
|
|
276
|
+
const { stdout, stderr } = await execFileAsync(this.signalCliPath, fullArgs, {
|
|
277
|
+
timeout: 30000,
|
|
278
|
+
maxBuffer: 10 * 1024 * 1024, // 10MB
|
|
279
|
+
});
|
|
280
|
+
if (stderr) {
|
|
281
|
+
console.warn(`[Signal] stderr: ${stderr}`);
|
|
282
|
+
}
|
|
283
|
+
return stdout;
|
|
284
|
+
}
|
|
285
|
+
catch (err) {
|
|
286
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
287
|
+
throw new Error(`signal-cli command failed: ${message}`);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
// ── Private: daemon mode ──
|
|
291
|
+
async connectDaemon() {
|
|
292
|
+
if (!this.daemonSocket)
|
|
293
|
+
return;
|
|
294
|
+
try {
|
|
295
|
+
const net = await import('node:net');
|
|
296
|
+
await new Promise((resolve, reject) => {
|
|
297
|
+
const socket = net.createConnection(this.daemonSocket, () => {
|
|
298
|
+
this.daemonConnection = socket;
|
|
299
|
+
resolve();
|
|
300
|
+
});
|
|
301
|
+
socket.on('error', (err) => {
|
|
302
|
+
reject(new Error(`Failed to connect to signal-cli daemon at ${this.daemonSocket}: ${err.message}`));
|
|
303
|
+
});
|
|
304
|
+
socket.on('data', (data) => {
|
|
305
|
+
this.handleDaemonData(data.toString());
|
|
306
|
+
});
|
|
307
|
+
socket.on('close', () => {
|
|
308
|
+
if (this.status === 'connected') {
|
|
309
|
+
console.warn('[Signal] Daemon connection closed unexpectedly.');
|
|
310
|
+
this.setStatus('reconnecting', 'Daemon connection closed');
|
|
311
|
+
this.reconnect().catch((e) => {
|
|
312
|
+
console.error('[Signal] Daemon reconnect failed:', e);
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
// Timeout after 10s
|
|
317
|
+
setTimeout(() => reject(new Error('Daemon connection timeout')), 10000);
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
catch (err) {
|
|
321
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
322
|
+
throw new Error(`Signal daemon connection failed: ${message}`);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
handleDaemonData(data) {
|
|
326
|
+
// signal-cli daemon sends newline-delimited JSON
|
|
327
|
+
const lines = data.split('\n').filter(Boolean);
|
|
328
|
+
for (const line of lines) {
|
|
329
|
+
try {
|
|
330
|
+
const event = JSON.parse(line);
|
|
331
|
+
this.processSignalEvent(event);
|
|
332
|
+
}
|
|
333
|
+
catch {
|
|
334
|
+
// Malformed JSON — skip
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
// ── Private: subprocess polling ──
|
|
339
|
+
startReceivePolling() {
|
|
340
|
+
// Poll for new messages every 15 seconds
|
|
341
|
+
this.pollTimer = setInterval(() => {
|
|
342
|
+
this.receiveMessages().catch((err) => {
|
|
343
|
+
console.warn('[Signal] Receive poll error:', err);
|
|
344
|
+
});
|
|
345
|
+
}, 15000);
|
|
346
|
+
// Also do an immediate receive
|
|
347
|
+
this.receiveMessages().catch(() => { });
|
|
348
|
+
}
|
|
349
|
+
async receiveMessages() {
|
|
350
|
+
try {
|
|
351
|
+
const output = await this.execSignalCli(['receive', '--timeout', '5']);
|
|
352
|
+
if (!output.trim())
|
|
353
|
+
return;
|
|
354
|
+
// Parse JSON output (may be array or newline-delimited objects)
|
|
355
|
+
let events; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
356
|
+
try {
|
|
357
|
+
const parsed = JSON.parse(output);
|
|
358
|
+
events = Array.isArray(parsed) ? parsed : [parsed];
|
|
359
|
+
}
|
|
360
|
+
catch {
|
|
361
|
+
// Try newline-delimited JSON
|
|
362
|
+
events = output
|
|
363
|
+
.split('\n')
|
|
364
|
+
.filter(Boolean)
|
|
365
|
+
.map((line) => {
|
|
366
|
+
try {
|
|
367
|
+
return JSON.parse(line);
|
|
368
|
+
}
|
|
369
|
+
catch {
|
|
370
|
+
return null;
|
|
371
|
+
}
|
|
372
|
+
})
|
|
373
|
+
.filter(Boolean);
|
|
374
|
+
}
|
|
375
|
+
for (const event of events) {
|
|
376
|
+
this.processSignalEvent(event);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
catch {
|
|
380
|
+
// Non-fatal — will retry on next poll
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
384
|
+
processSignalEvent(event) {
|
|
385
|
+
if (!event)
|
|
386
|
+
return;
|
|
387
|
+
// signal-cli JSON output wraps messages in an envelope
|
|
388
|
+
const envelope = event.envelope ?? event;
|
|
389
|
+
const dataMessage = envelope.dataMessage ?? envelope.syncMessage?.sentMessage;
|
|
390
|
+
if (!dataMessage)
|
|
391
|
+
return;
|
|
392
|
+
const senderNumber = envelope.source ?? envelope.sourceNumber ?? 'unknown';
|
|
393
|
+
const timestamp = envelope.timestamp ?? Date.now();
|
|
394
|
+
// Determine conversation type and ID
|
|
395
|
+
const groupInfo = dataMessage.groupInfo ?? dataMessage.group;
|
|
396
|
+
const isGroup = !!groupInfo;
|
|
397
|
+
const conversationId = isGroup
|
|
398
|
+
? `group:${groupInfo.groupId ?? groupInfo.id ?? 'unknown'}`
|
|
399
|
+
: senderNumber;
|
|
400
|
+
// Build content blocks
|
|
401
|
+
const contentBlocks = [];
|
|
402
|
+
if (dataMessage.message || dataMessage.body) {
|
|
403
|
+
contentBlocks.push({
|
|
404
|
+
type: 'text',
|
|
405
|
+
text: dataMessage.message ?? dataMessage.body ?? '',
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
// Handle attachments
|
|
409
|
+
if (dataMessage.attachments) {
|
|
410
|
+
for (const att of dataMessage.attachments) {
|
|
411
|
+
const mimeType = att.contentType ?? att.mimeType ?? '';
|
|
412
|
+
if (mimeType.startsWith('image/')) {
|
|
413
|
+
contentBlocks.push({
|
|
414
|
+
type: 'image',
|
|
415
|
+
url: att.filename ?? att.file ?? '',
|
|
416
|
+
mimeType,
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
else if (mimeType.startsWith('audio/')) {
|
|
420
|
+
contentBlocks.push({
|
|
421
|
+
type: 'audio',
|
|
422
|
+
url: att.filename ?? att.file ?? '',
|
|
423
|
+
mimeType,
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
else if (mimeType.startsWith('video/')) {
|
|
427
|
+
contentBlocks.push({
|
|
428
|
+
type: 'video',
|
|
429
|
+
url: att.filename ?? att.file ?? '',
|
|
430
|
+
mimeType,
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
else {
|
|
434
|
+
contentBlocks.push({
|
|
435
|
+
type: 'document',
|
|
436
|
+
url: att.filename ?? att.file ?? '',
|
|
437
|
+
filename: att.filename ?? 'attachment',
|
|
438
|
+
mimeType,
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
const textContent = contentBlocks
|
|
444
|
+
.filter((b) => b.type === 'text')
|
|
445
|
+
.map((b) => b.text)
|
|
446
|
+
.join('\n');
|
|
447
|
+
const message = {
|
|
448
|
+
messageId: `${timestamp}:${senderNumber}`,
|
|
449
|
+
platform: 'signal',
|
|
450
|
+
conversationId,
|
|
451
|
+
conversationType: isGroup ? 'group' : 'direct',
|
|
452
|
+
sender: {
|
|
453
|
+
id: senderNumber,
|
|
454
|
+
username: senderNumber,
|
|
455
|
+
displayName: envelope.sourceName ?? senderNumber,
|
|
456
|
+
},
|
|
457
|
+
content: contentBlocks.length > 0 ? contentBlocks : [{ type: 'text', text: '' }],
|
|
458
|
+
text: textContent,
|
|
459
|
+
timestamp: new Date(timestamp).toISOString(),
|
|
460
|
+
rawEvent: event,
|
|
461
|
+
};
|
|
462
|
+
this.emit({
|
|
463
|
+
type: 'message',
|
|
464
|
+
platform: 'signal',
|
|
465
|
+
conversationId,
|
|
466
|
+
timestamp: message.timestamp,
|
|
467
|
+
data: message,
|
|
468
|
+
});
|
|
469
|
+
// Handle reactions
|
|
470
|
+
if (dataMessage.reaction) {
|
|
471
|
+
this.emit({
|
|
472
|
+
type: 'reaction_added',
|
|
473
|
+
platform: 'signal',
|
|
474
|
+
conversationId,
|
|
475
|
+
timestamp: new Date(timestamp).toISOString(),
|
|
476
|
+
data: {
|
|
477
|
+
emoji: dataMessage.reaction.emoji,
|
|
478
|
+
targetAuthor: dataMessage.reaction.targetAuthor,
|
|
479
|
+
targetTimestamp: dataMessage.reaction.targetSentTimestamp,
|
|
480
|
+
sender: {
|
|
481
|
+
id: senderNumber,
|
|
482
|
+
username: senderNumber,
|
|
483
|
+
},
|
|
484
|
+
},
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
// ── Text/Attachment helpers ──
|
|
489
|
+
extractText(blocks) {
|
|
490
|
+
return blocks
|
|
491
|
+
.filter((b) => b.type === 'text')
|
|
492
|
+
.map((b) => b.text)
|
|
493
|
+
.join('\n');
|
|
494
|
+
}
|
|
495
|
+
/**
|
|
496
|
+
* Extract file paths from attachment blocks. For Signal, URLs
|
|
497
|
+
* must be local file paths (signal-cli does not support remote URLs
|
|
498
|
+
* directly — the caller must download first).
|
|
499
|
+
*/
|
|
500
|
+
extractAttachmentPaths(blocks) {
|
|
501
|
+
const paths = [];
|
|
502
|
+
for (const block of blocks) {
|
|
503
|
+
if (block.type === 'image' ||
|
|
504
|
+
block.type === 'audio' ||
|
|
505
|
+
block.type === 'video' ||
|
|
506
|
+
block.type === 'document') {
|
|
507
|
+
const url = 'url' in block ? block.url : undefined;
|
|
508
|
+
if (url && !url.startsWith('http://') && !url.startsWith('https://')) {
|
|
509
|
+
// Local file path — usable by signal-cli
|
|
510
|
+
paths.push(url);
|
|
511
|
+
}
|
|
512
|
+
else if (url) {
|
|
513
|
+
console.warn(`[Signal] Skipping remote URL attachment "${url}". ` +
|
|
514
|
+
'Signal requires local file paths. Download the file first.');
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
return paths;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
//# sourceMappingURL=SignalChannelAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SignalChannelAdapter.js","sourceRoot":"","sources":["../../../src/channels/adapters/SignalChannelAdapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Slack Channel Adapter for AgentOS.
|
|
3
|
+
*
|
|
4
|
+
* Wraps the `@slack/bolt` npm package to connect agents to Slack
|
|
5
|
+
* workspaces. Supports rich messaging including text (mrkdwn), images,
|
|
6
|
+
* documents, Block Kit components, reactions, threads, and mentions.
|
|
7
|
+
*
|
|
8
|
+
* **Dependencies**: Requires `@slack/bolt` to be installed. The adapter
|
|
9
|
+
* uses a dynamic import so the package is only loaded at connection time,
|
|
10
|
+
* avoiding hard failures if it is not present.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const slack = new SlackChannelAdapter();
|
|
15
|
+
* await slack.initialize({
|
|
16
|
+
* platform: 'slack',
|
|
17
|
+
* credential: 'xoxb-BOT-TOKEN',
|
|
18
|
+
* params: {
|
|
19
|
+
* botToken: 'xoxb-BOT-TOKEN',
|
|
20
|
+
* signingSecret: 'SIGNING_SECRET',
|
|
21
|
+
* appToken: 'xapp-APP-TOKEN', // for Socket Mode
|
|
22
|
+
* },
|
|
23
|
+
* });
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @module @framers/agentos/channels/adapters/SlackChannelAdapter
|
|
27
|
+
*/
|
|
28
|
+
import type { ChannelAuthConfig, ChannelCapability, ChannelPlatform, ChannelSendResult, MessageContent } from '../types.js';
|
|
29
|
+
import { BaseChannelAdapter } from './BaseChannelAdapter.js';
|
|
30
|
+
/** Platform-specific parameters for Slack connections. */
|
|
31
|
+
export interface SlackAuthParams extends Record<string, string | undefined> {
|
|
32
|
+
/** Bot token (xoxb-*). If provided, overrides credential. */
|
|
33
|
+
botToken?: string;
|
|
34
|
+
/** Signing secret for verifying Slack requests. */
|
|
35
|
+
signingSecret?: string;
|
|
36
|
+
/** App-level token (xapp-*) for Socket Mode. If omitted, HTTP mode is used. */
|
|
37
|
+
appToken?: string;
|
|
38
|
+
/** Port for HTTP mode (default: '3000'). Ignored when using Socket Mode. */
|
|
39
|
+
port?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Channel adapter for Slack using the @slack/bolt SDK.
|
|
43
|
+
*
|
|
44
|
+
* Uses dynamic import so `@slack/bolt` is only required at runtime when
|
|
45
|
+
* the adapter is actually initialized.
|
|
46
|
+
*
|
|
47
|
+
* When `appToken` is provided, the adapter uses Socket Mode (no public
|
|
48
|
+
* endpoint required). Otherwise, it starts an HTTP server for receiving
|
|
49
|
+
* Slack events.
|
|
50
|
+
*
|
|
51
|
+
* Capabilities: text, rich_text, images, documents, reactions, threads,
|
|
52
|
+
* mentions, buttons, group_chat, channels, editing, deletion.
|
|
53
|
+
*/
|
|
54
|
+
export declare class SlackChannelAdapter extends BaseChannelAdapter<SlackAuthParams> {
|
|
55
|
+
readonly platform: ChannelPlatform;
|
|
56
|
+
readonly displayName = "Slack";
|
|
57
|
+
readonly capabilities: readonly ChannelCapability[];
|
|
58
|
+
/** The @slack/bolt App instance. */
|
|
59
|
+
private app;
|
|
60
|
+
/** Bot user ID, resolved after connection. */
|
|
61
|
+
private botUserId;
|
|
62
|
+
/** Whether socket mode is active. */
|
|
63
|
+
private socketMode;
|
|
64
|
+
protected doConnect(auth: ChannelAuthConfig & {
|
|
65
|
+
params?: SlackAuthParams;
|
|
66
|
+
}): Promise<void>;
|
|
67
|
+
protected doSendMessage(conversationId: string, content: MessageContent): Promise<ChannelSendResult>;
|
|
68
|
+
protected doShutdown(): Promise<void>;
|
|
69
|
+
editMessage(conversationId: string, messageId: string, content: MessageContent): Promise<void>;
|
|
70
|
+
deleteMessage(conversationId: string, messageId: string): Promise<void>;
|
|
71
|
+
addReaction(conversationId: string, messageId: string, emoji: string): Promise<void>;
|
|
72
|
+
sendTypingIndicator(_conversationId: string, _isTyping: boolean): Promise<void>;
|
|
73
|
+
getConversationInfo(conversationId: string): Promise<{
|
|
74
|
+
name?: string;
|
|
75
|
+
memberCount?: number;
|
|
76
|
+
isGroup: boolean;
|
|
77
|
+
metadata?: Record<string, unknown>;
|
|
78
|
+
}>;
|
|
79
|
+
/**
|
|
80
|
+
* Wire up @slack/bolt event handlers for inbound messages.
|
|
81
|
+
*/
|
|
82
|
+
private wireEventHandlers;
|
|
83
|
+
/**
|
|
84
|
+
* Handle an inbound Slack message and emit a channel event.
|
|
85
|
+
*/
|
|
86
|
+
private handleInboundMessage;
|
|
87
|
+
/**
|
|
88
|
+
* Build the full Slack API payload for chat.postMessage.
|
|
89
|
+
*/
|
|
90
|
+
private buildSlackPayload;
|
|
91
|
+
/**
|
|
92
|
+
* Build Slack Block Kit blocks from MessageContent.
|
|
93
|
+
*/
|
|
94
|
+
private buildBlockKit;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=SlackChannelAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SlackChannelAdapter.d.ts","sourceRoot":"","sources":["../../../src/channels/adapters/SlackChannelAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EAEjB,eAAe,EACf,iBAAiB,EACjB,cAAc,EAEf,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAM7D,0DAA0D;AAC1D,MAAM,WAAW,eAAgB,SAAQ,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACzE,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAMD;;;;;;;;;;;;GAYG;AACH,qBAAa,mBAAoB,SAAQ,kBAAkB,CAAC,eAAe,CAAC;IAC1E,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAW;IAC7C,QAAQ,CAAC,WAAW,WAAW;IAC/B,QAAQ,CAAC,YAAY,EAAE,SAAS,iBAAiB,EAAE,CAaxC;IAEX,oCAAoC;IAEpC,OAAO,CAAC,GAAG,CAAkB;IAE7B,8CAA8C;IAC9C,OAAO,CAAC,SAAS,CAAqB;IAEtC,qCAAqC;IACrC,OAAO,CAAC,UAAU,CAAS;cAIX,SAAS,CACvB,IAAI,EAAE,iBAAiB,GAAG;QAAE,MAAM,CAAC,EAAE,eAAe,CAAA;KAAE,GACrD,OAAO,CAAC,IAAI,CAAC;cAwEA,aAAa,CAC3B,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,iBAAiB,CAAC;cAkBb,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAerC,WAAW,CACf,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,IAAI,CAAC;IAeV,aAAa,CACjB,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC;IASV,WAAW,CACf,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC;IAYV,mBAAmB,CACvB,eAAe,EAAE,MAAM,EACvB,SAAS,EAAE,OAAO,GACjB,OAAO,CAAC,IAAI,CAAC;IAKV,mBAAmB,CACvB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IAwBzG;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAuGzB;;OAEG;IAEH,OAAO,CAAC,oBAAoB;IAuF5B;;OAEG;IAEH,OAAO,CAAC,iBAAiB;IAgCzB;;OAEG;IAEH,OAAO,CAAC,aAAa;CAkHtB"}
|