machinaos 0.0.21 → 0.0.23
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 +32 -6
- package/bin/cli.js +0 -0
- package/client/dist/assets/index-5BWZnM6b.js +703 -0
- package/client/dist/index.html +1 -1
- package/client/package.json +1 -1
- package/client/src/Dashboard.tsx +12 -5
- package/client/src/ParameterPanel.tsx +6 -5
- package/client/src/components/AIAgentNode.tsx +35 -16
- package/client/src/components/CredentialsModal.tsx +450 -5
- package/client/src/components/TeamMonitorNode.tsx +269 -0
- package/client/src/components/parameterPanel/InputSection.tsx +25 -0
- package/client/src/contexts/WebSocketContext.tsx +38 -0
- package/client/src/hooks/useApiKeys.ts +44 -0
- package/client/src/nodeDefinitions/specializedAgentNodes.ts +59 -3
- package/client/src/nodeDefinitions/twitterNodes.ts +441 -0
- package/client/src/nodeDefinitions/utilityNodes.ts +45 -1
- package/client/src/nodeDefinitions.ts +7 -1
- package/client/src/services/executionService.ts +4 -1
- package/install.sh +63 -1
- package/package.json +5 -2
- package/scripts/build.js +0 -0
- package/scripts/clean.js +0 -0
- package/scripts/daemon.js +0 -0
- package/scripts/docker.js +0 -0
- package/scripts/install.js +0 -0
- package/scripts/postinstall.js +29 -0
- package/scripts/preinstall.js +67 -0
- package/scripts/serve-client.js +0 -0
- package/scripts/start.js +0 -0
- package/scripts/stop.js +0 -0
- package/scripts/sync-version.js +0 -0
- package/server/Dockerfile +10 -15
- package/server/constants.py +20 -0
- package/server/core/database.py +443 -3
- package/server/main.py +9 -1
- package/server/models/database.py +112 -2
- package/server/pyproject.toml +3 -0
- package/server/requirements.txt +3 -0
- package/server/routers/twitter.py +390 -0
- package/server/routers/websocket.py +320 -0
- package/server/services/agent_team.py +266 -0
- package/server/services/ai.py +43 -0
- package/server/services/compaction.py +39 -4
- package/server/services/event_waiter.py +41 -0
- package/server/services/handlers/__init__.py +13 -0
- package/server/services/handlers/ai.py +66 -2
- package/server/services/handlers/tools.py +84 -0
- package/server/services/handlers/twitter.py +297 -0
- package/server/services/handlers/utility.py +91 -0
- package/server/services/node_executor.py +15 -1
- package/server/services/pricing.py +270 -0
- package/server/services/status_broadcaster.py +79 -0
- package/server/services/twitter_oauth.py +410 -0
- package/server/skills/social_agent/twitter-search-skill/SKILL.md +146 -0
- package/server/skills/social_agent/twitter-send-skill/SKILL.md +142 -0
- package/server/skills/social_agent/twitter-user-skill/SKILL.md +165 -0
- package/workflows/Zeenie_full.json +459 -0
- package/workflows/Zeenie_small.json +459 -0
- package/client/dist/assets/index-YVvAiByx.js +0 -703
- package/server/requirements-docker.txt +0 -86
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
// Twitter/X Node Definitions - X API v2 integration via OAuth 2.0
|
|
2
|
+
import {
|
|
3
|
+
INodeTypeDescription,
|
|
4
|
+
NodeConnectionType
|
|
5
|
+
} from '../types/INodeProperties';
|
|
6
|
+
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// TWITTER ICONS (SVG Data URIs) - X Brand black color
|
|
9
|
+
// ============================================================================
|
|
10
|
+
|
|
11
|
+
// Twitter/X Logo - Official X logo (white fill for dark backgrounds)
|
|
12
|
+
export const TWITTER_ICON = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23FFFFFF'%3E%3Cpath d='M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z'/%3E%3C/svg%3E";
|
|
13
|
+
|
|
14
|
+
// All Twitter nodes use the X logo
|
|
15
|
+
const TWITTER_SEND_ICON = TWITTER_ICON;
|
|
16
|
+
const TWITTER_RECEIVE_ICON = TWITTER_ICON;
|
|
17
|
+
const TWITTER_SEARCH_ICON = TWITTER_ICON;
|
|
18
|
+
const TWITTER_USER_ICON = TWITTER_ICON;
|
|
19
|
+
|
|
20
|
+
// ============================================================================
|
|
21
|
+
// TWITTER NODES
|
|
22
|
+
// ============================================================================
|
|
23
|
+
|
|
24
|
+
export const twitterNodes: Record<string, INodeTypeDescription> = {
|
|
25
|
+
// Twitter Send - Post tweets, reply, retweet, like
|
|
26
|
+
twitterSend: {
|
|
27
|
+
displayName: 'Twitter Send',
|
|
28
|
+
name: 'twitterSend',
|
|
29
|
+
icon: TWITTER_SEND_ICON,
|
|
30
|
+
group: ['social', 'tool'],
|
|
31
|
+
version: 1,
|
|
32
|
+
subtitle: 'Post to Twitter/X',
|
|
33
|
+
description: 'Post tweets, reply, retweet, like, or delete tweets on Twitter/X',
|
|
34
|
+
defaults: { name: 'Twitter Send', color: '#000000' },
|
|
35
|
+
inputs: [{
|
|
36
|
+
name: 'main',
|
|
37
|
+
displayName: 'Input',
|
|
38
|
+
type: 'main' as NodeConnectionType,
|
|
39
|
+
description: 'Tweet input'
|
|
40
|
+
}],
|
|
41
|
+
outputs: [
|
|
42
|
+
{
|
|
43
|
+
name: 'main',
|
|
44
|
+
displayName: 'Output',
|
|
45
|
+
type: 'main' as NodeConnectionType,
|
|
46
|
+
description: 'Tweet result'
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: 'tool',
|
|
50
|
+
displayName: 'Tool',
|
|
51
|
+
type: 'main' as NodeConnectionType,
|
|
52
|
+
description: 'Connect to AI Agent tool handle'
|
|
53
|
+
}
|
|
54
|
+
],
|
|
55
|
+
properties: [
|
|
56
|
+
// ===== ACTION =====
|
|
57
|
+
{
|
|
58
|
+
displayName: 'Action',
|
|
59
|
+
name: 'action',
|
|
60
|
+
type: 'options',
|
|
61
|
+
options: [
|
|
62
|
+
{ name: 'Post Tweet', value: 'tweet' },
|
|
63
|
+
{ name: 'Reply to Tweet', value: 'reply' },
|
|
64
|
+
{ name: 'Retweet', value: 'retweet' },
|
|
65
|
+
{ name: 'Quote Tweet', value: 'quote' },
|
|
66
|
+
{ name: 'Like Tweet', value: 'like' },
|
|
67
|
+
{ name: 'Unlike Tweet', value: 'unlike' },
|
|
68
|
+
{ name: 'Delete Tweet', value: 'delete' }
|
|
69
|
+
],
|
|
70
|
+
default: 'tweet',
|
|
71
|
+
description: 'Action to perform on Twitter'
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
// ===== TWEET TEXT (for tweet, reply, quote) =====
|
|
75
|
+
{
|
|
76
|
+
displayName: 'Tweet Text',
|
|
77
|
+
name: 'text',
|
|
78
|
+
type: 'string',
|
|
79
|
+
default: '',
|
|
80
|
+
required: true,
|
|
81
|
+
typeOptions: { rows: 4 },
|
|
82
|
+
description: 'Tweet content (max 280 characters)',
|
|
83
|
+
placeholder: "What's happening?",
|
|
84
|
+
displayOptions: {
|
|
85
|
+
show: { action: ['tweet', 'reply', 'quote'] }
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
// ===== TWEET ID (for reply, retweet, quote, like, unlike, delete) =====
|
|
90
|
+
{
|
|
91
|
+
displayName: 'Tweet ID',
|
|
92
|
+
name: 'tweet_id',
|
|
93
|
+
type: 'string',
|
|
94
|
+
default: '',
|
|
95
|
+
required: true,
|
|
96
|
+
placeholder: '1234567890123456789',
|
|
97
|
+
description: 'ID of the tweet to interact with',
|
|
98
|
+
displayOptions: {
|
|
99
|
+
show: { action: ['reply', 'retweet', 'quote', 'like', 'unlike', 'delete'] }
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
// ===== MEDIA (for tweet, reply, quote) =====
|
|
104
|
+
{
|
|
105
|
+
displayName: 'Include Media',
|
|
106
|
+
name: 'include_media',
|
|
107
|
+
type: 'boolean',
|
|
108
|
+
default: false,
|
|
109
|
+
description: 'Attach images or videos to the tweet',
|
|
110
|
+
displayOptions: {
|
|
111
|
+
show: { action: ['tweet', 'reply', 'quote'] }
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
displayName: 'Media URLs',
|
|
116
|
+
name: 'media_urls',
|
|
117
|
+
type: 'string',
|
|
118
|
+
default: '',
|
|
119
|
+
placeholder: 'https://example.com/image1.jpg, https://example.com/image2.jpg',
|
|
120
|
+
description: 'Comma-separated URLs of media to attach (max 4 images or 1 video)',
|
|
121
|
+
displayOptions: {
|
|
122
|
+
show: { action: ['tweet', 'reply', 'quote'], include_media: [true] }
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
|
|
126
|
+
// ===== POLL (for tweet) =====
|
|
127
|
+
{
|
|
128
|
+
displayName: 'Include Poll',
|
|
129
|
+
name: 'include_poll',
|
|
130
|
+
type: 'boolean',
|
|
131
|
+
default: false,
|
|
132
|
+
description: 'Create a poll with this tweet',
|
|
133
|
+
displayOptions: {
|
|
134
|
+
show: { action: ['tweet'] }
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
displayName: 'Poll Options',
|
|
139
|
+
name: 'poll_options',
|
|
140
|
+
type: 'string',
|
|
141
|
+
default: '',
|
|
142
|
+
placeholder: 'Option 1, Option 2, Option 3',
|
|
143
|
+
description: 'Comma-separated poll options (2-4 options, max 25 chars each)',
|
|
144
|
+
displayOptions: {
|
|
145
|
+
show: { action: ['tweet'], include_poll: [true] }
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
displayName: 'Poll Duration (minutes)',
|
|
150
|
+
name: 'poll_duration',
|
|
151
|
+
type: 'number',
|
|
152
|
+
default: 1440,
|
|
153
|
+
typeOptions: { minValue: 5, maxValue: 10080 },
|
|
154
|
+
description: 'Poll duration in minutes (5 min - 7 days)',
|
|
155
|
+
displayOptions: {
|
|
156
|
+
show: { action: ['tweet'], include_poll: [true] }
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
]
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
// Twitter Receive - Trigger on mentions, searches, timeline updates
|
|
163
|
+
twitterReceive: {
|
|
164
|
+
displayName: 'Twitter Receive',
|
|
165
|
+
name: 'twitterReceive',
|
|
166
|
+
icon: TWITTER_RECEIVE_ICON,
|
|
167
|
+
group: ['social', 'trigger'],
|
|
168
|
+
version: 1,
|
|
169
|
+
subtitle: 'On Twitter Event',
|
|
170
|
+
description: 'Trigger workflow on Twitter mentions, search results, or timeline updates (polling-based)',
|
|
171
|
+
defaults: { name: 'Twitter Receive', color: '#1DA1F2' },
|
|
172
|
+
inputs: [],
|
|
173
|
+
outputs: [{
|
|
174
|
+
name: 'main',
|
|
175
|
+
displayName: 'Tweet',
|
|
176
|
+
type: 'main' as NodeConnectionType,
|
|
177
|
+
description: 'Received tweet data (tweet_id, text, author_id, author_username, created_at, metrics)'
|
|
178
|
+
}],
|
|
179
|
+
properties: [
|
|
180
|
+
// ===== TRIGGER TYPE =====
|
|
181
|
+
{
|
|
182
|
+
displayName: 'Trigger On',
|
|
183
|
+
name: 'trigger_type',
|
|
184
|
+
type: 'options',
|
|
185
|
+
options: [
|
|
186
|
+
{ name: 'Mentions', value: 'mentions' },
|
|
187
|
+
{ name: 'Search Results', value: 'search' },
|
|
188
|
+
{ name: 'User Timeline', value: 'timeline' }
|
|
189
|
+
],
|
|
190
|
+
default: 'mentions',
|
|
191
|
+
description: 'What events should trigger this workflow'
|
|
192
|
+
},
|
|
193
|
+
|
|
194
|
+
// ===== SEARCH QUERY (for search trigger) =====
|
|
195
|
+
{
|
|
196
|
+
displayName: 'Search Query',
|
|
197
|
+
name: 'search_query',
|
|
198
|
+
type: 'string',
|
|
199
|
+
default: '',
|
|
200
|
+
required: true,
|
|
201
|
+
placeholder: 'from:elonmusk OR #AI',
|
|
202
|
+
description: 'Twitter search query (supports operators like from:, to:, #, -)',
|
|
203
|
+
displayOptions: {
|
|
204
|
+
show: { trigger_type: ['search'] }
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
|
|
208
|
+
// ===== USER ID (for timeline trigger) =====
|
|
209
|
+
{
|
|
210
|
+
displayName: 'User ID',
|
|
211
|
+
name: 'user_id',
|
|
212
|
+
type: 'string',
|
|
213
|
+
default: '',
|
|
214
|
+
placeholder: '12345678',
|
|
215
|
+
description: 'Twitter user ID to monitor (leave empty for authenticated user)',
|
|
216
|
+
displayOptions: {
|
|
217
|
+
show: { trigger_type: ['timeline'] }
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
|
|
221
|
+
// ===== OPTIONS =====
|
|
222
|
+
{
|
|
223
|
+
displayName: 'Filter Retweets',
|
|
224
|
+
name: 'filter_retweets',
|
|
225
|
+
type: 'boolean',
|
|
226
|
+
default: true,
|
|
227
|
+
description: 'Exclude retweets from results'
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
displayName: 'Filter Replies',
|
|
231
|
+
name: 'filter_replies',
|
|
232
|
+
type: 'boolean',
|
|
233
|
+
default: false,
|
|
234
|
+
description: 'Exclude replies from results'
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
displayName: 'Poll Interval (seconds)',
|
|
238
|
+
name: 'poll_interval',
|
|
239
|
+
type: 'number',
|
|
240
|
+
default: 60,
|
|
241
|
+
typeOptions: { minValue: 15, maxValue: 3600 },
|
|
242
|
+
description: 'How often to check for new tweets (15s - 1 hour)'
|
|
243
|
+
}
|
|
244
|
+
]
|
|
245
|
+
},
|
|
246
|
+
|
|
247
|
+
// Twitter Search - Search recent tweets
|
|
248
|
+
twitterSearch: {
|
|
249
|
+
displayName: 'Twitter Search',
|
|
250
|
+
name: 'twitterSearch',
|
|
251
|
+
icon: TWITTER_SEARCH_ICON,
|
|
252
|
+
group: ['social', 'tool'],
|
|
253
|
+
version: 1,
|
|
254
|
+
subtitle: 'Search Tweets',
|
|
255
|
+
description: 'Search recent tweets on Twitter/X using the Search API',
|
|
256
|
+
defaults: { name: 'Twitter Search', color: '#1DA1F2' },
|
|
257
|
+
inputs: [{
|
|
258
|
+
name: 'main',
|
|
259
|
+
displayName: 'Input',
|
|
260
|
+
type: 'main' as NodeConnectionType,
|
|
261
|
+
description: 'Search input'
|
|
262
|
+
}],
|
|
263
|
+
outputs: [
|
|
264
|
+
{
|
|
265
|
+
name: 'main',
|
|
266
|
+
displayName: 'Output',
|
|
267
|
+
type: 'main' as NodeConnectionType,
|
|
268
|
+
description: 'Search results'
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
name: 'tool',
|
|
272
|
+
displayName: 'Tool',
|
|
273
|
+
type: 'main' as NodeConnectionType,
|
|
274
|
+
description: 'Connect to AI Agent tool handle'
|
|
275
|
+
}
|
|
276
|
+
],
|
|
277
|
+
properties: [
|
|
278
|
+
// ===== SEARCH QUERY =====
|
|
279
|
+
{
|
|
280
|
+
displayName: 'Search Query',
|
|
281
|
+
name: 'query',
|
|
282
|
+
type: 'string',
|
|
283
|
+
default: '',
|
|
284
|
+
required: true,
|
|
285
|
+
placeholder: '#AI lang:en -is:retweet',
|
|
286
|
+
description: 'Twitter search query with operators'
|
|
287
|
+
},
|
|
288
|
+
|
|
289
|
+
// ===== RESULT OPTIONS =====
|
|
290
|
+
{
|
|
291
|
+
displayName: 'Max Results',
|
|
292
|
+
name: 'max_results',
|
|
293
|
+
type: 'number',
|
|
294
|
+
default: 10,
|
|
295
|
+
typeOptions: { minValue: 10, maxValue: 100 },
|
|
296
|
+
description: 'Maximum number of tweets to return (10-100)'
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
displayName: 'Sort Order',
|
|
300
|
+
name: 'sort_order',
|
|
301
|
+
type: 'options',
|
|
302
|
+
options: [
|
|
303
|
+
{ name: 'Recent', value: 'recency' },
|
|
304
|
+
{ name: 'Relevance', value: 'relevancy' }
|
|
305
|
+
],
|
|
306
|
+
default: 'recency',
|
|
307
|
+
description: 'Sort order for results'
|
|
308
|
+
},
|
|
309
|
+
|
|
310
|
+
// ===== TIME FILTERS =====
|
|
311
|
+
{
|
|
312
|
+
displayName: 'Start Time',
|
|
313
|
+
name: 'start_time',
|
|
314
|
+
type: 'string',
|
|
315
|
+
default: '',
|
|
316
|
+
placeholder: '2024-01-01T00:00:00Z',
|
|
317
|
+
description: 'Start time for search (ISO 8601 format, optional)'
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
displayName: 'End Time',
|
|
321
|
+
name: 'end_time',
|
|
322
|
+
type: 'string',
|
|
323
|
+
default: '',
|
|
324
|
+
placeholder: '2024-01-31T23:59:59Z',
|
|
325
|
+
description: 'End time for search (ISO 8601 format, optional)'
|
|
326
|
+
},
|
|
327
|
+
|
|
328
|
+
// ===== INCLUDE OPTIONS =====
|
|
329
|
+
{
|
|
330
|
+
displayName: 'Include Metrics',
|
|
331
|
+
name: 'include_metrics',
|
|
332
|
+
type: 'boolean',
|
|
333
|
+
default: true,
|
|
334
|
+
description: 'Include tweet engagement metrics (likes, retweets, replies)'
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
displayName: 'Include Author Info',
|
|
338
|
+
name: 'include_author',
|
|
339
|
+
type: 'boolean',
|
|
340
|
+
default: true,
|
|
341
|
+
description: 'Include author details (username, name, profile)'
|
|
342
|
+
}
|
|
343
|
+
]
|
|
344
|
+
},
|
|
345
|
+
|
|
346
|
+
// Twitter User - User lookup and profile operations (dual-purpose: workflow + AI tool)
|
|
347
|
+
twitterUser: {
|
|
348
|
+
displayName: 'Twitter User',
|
|
349
|
+
name: 'twitterUser',
|
|
350
|
+
icon: TWITTER_USER_ICON,
|
|
351
|
+
group: ['social', 'tool'],
|
|
352
|
+
version: 1,
|
|
353
|
+
subtitle: 'User Operations',
|
|
354
|
+
description: 'Look up Twitter users, get profile info, followers, following',
|
|
355
|
+
defaults: { name: 'Twitter User', color: '#1DA1F2' },
|
|
356
|
+
inputs: [{
|
|
357
|
+
name: 'main',
|
|
358
|
+
displayName: 'Input',
|
|
359
|
+
type: 'main' as NodeConnectionType,
|
|
360
|
+
description: 'User lookup input'
|
|
361
|
+
}],
|
|
362
|
+
outputs: [
|
|
363
|
+
{
|
|
364
|
+
name: 'main',
|
|
365
|
+
displayName: 'Output',
|
|
366
|
+
type: 'main' as NodeConnectionType,
|
|
367
|
+
description: 'User data'
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
name: 'tool',
|
|
371
|
+
displayName: 'Tool',
|
|
372
|
+
type: 'main' as NodeConnectionType,
|
|
373
|
+
description: 'Connect to AI Agent input-tools handle'
|
|
374
|
+
}
|
|
375
|
+
],
|
|
376
|
+
properties: [
|
|
377
|
+
// ===== OPERATION =====
|
|
378
|
+
{
|
|
379
|
+
displayName: 'Operation',
|
|
380
|
+
name: 'operation',
|
|
381
|
+
type: 'options',
|
|
382
|
+
options: [
|
|
383
|
+
{ name: 'Get My Profile', value: 'me' },
|
|
384
|
+
{ name: 'Lookup by Username', value: 'by_username' },
|
|
385
|
+
{ name: 'Lookup by ID', value: 'by_id' },
|
|
386
|
+
{ name: 'Get Followers', value: 'followers' },
|
|
387
|
+
{ name: 'Get Following', value: 'following' }
|
|
388
|
+
],
|
|
389
|
+
default: 'me',
|
|
390
|
+
description: 'User operation to perform'
|
|
391
|
+
},
|
|
392
|
+
|
|
393
|
+
// ===== USERNAME (for by_username) =====
|
|
394
|
+
{
|
|
395
|
+
displayName: 'Username',
|
|
396
|
+
name: 'username',
|
|
397
|
+
type: 'string',
|
|
398
|
+
default: '',
|
|
399
|
+
required: true,
|
|
400
|
+
placeholder: 'elonmusk',
|
|
401
|
+
description: 'Twitter username (without @)',
|
|
402
|
+
displayOptions: {
|
|
403
|
+
show: { operation: ['by_username'] }
|
|
404
|
+
}
|
|
405
|
+
},
|
|
406
|
+
|
|
407
|
+
// ===== USER ID (for by_id, followers, following) =====
|
|
408
|
+
{
|
|
409
|
+
displayName: 'User ID',
|
|
410
|
+
name: 'user_id',
|
|
411
|
+
type: 'string',
|
|
412
|
+
default: '',
|
|
413
|
+
required: true,
|
|
414
|
+
placeholder: '44196397',
|
|
415
|
+
description: 'Twitter user ID',
|
|
416
|
+
displayOptions: {
|
|
417
|
+
show: { operation: ['by_id', 'followers', 'following'] }
|
|
418
|
+
}
|
|
419
|
+
},
|
|
420
|
+
|
|
421
|
+
// ===== PAGINATION (for followers, following) =====
|
|
422
|
+
{
|
|
423
|
+
displayName: 'Max Results',
|
|
424
|
+
name: 'max_results',
|
|
425
|
+
type: 'number',
|
|
426
|
+
default: 100,
|
|
427
|
+
typeOptions: { minValue: 1, maxValue: 1000 },
|
|
428
|
+
description: 'Maximum number of users to return',
|
|
429
|
+
displayOptions: {
|
|
430
|
+
show: { operation: ['followers', 'following'] }
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
]
|
|
434
|
+
}
|
|
435
|
+
};
|
|
436
|
+
|
|
437
|
+
// ============================================================================
|
|
438
|
+
// EXPORTS
|
|
439
|
+
// ============================================================================
|
|
440
|
+
|
|
441
|
+
export const TWITTER_NODE_TYPES = ['twitterSend', 'twitterReceive', 'twitterSearch', 'twitterUser'];
|
|
@@ -278,7 +278,51 @@ export const utilityNodes: Record<string, INodeTypeDescription> = {
|
|
|
278
278
|
description: 'Output format for the log'
|
|
279
279
|
}
|
|
280
280
|
]
|
|
281
|
+
},
|
|
282
|
+
|
|
283
|
+
teamMonitor: {
|
|
284
|
+
displayName: 'Team Monitor',
|
|
285
|
+
name: 'teamMonitor',
|
|
286
|
+
icon: '📊',
|
|
287
|
+
group: ['utility', 'agent'],
|
|
288
|
+
version: 1,
|
|
289
|
+
description: 'Monitor agent team operations, tasks, and messages in real-time',
|
|
290
|
+
defaults: { name: 'Team Monitor', color: '#8b5cf6' },
|
|
291
|
+
inputs: [{ name: 'team', displayName: 'Team', type: 'main' as NodeConnectionType, description: 'Connect to AI Employee or Orchestrator Agent node' }],
|
|
292
|
+
outputs: [{ name: 'main', displayName: 'Events', type: 'main' as NodeConnectionType, description: 'task_completed, task_failed, message_received, team_status' }],
|
|
293
|
+
properties: [
|
|
294
|
+
{
|
|
295
|
+
displayName: 'Auto-Refresh Interval',
|
|
296
|
+
name: 'refreshInterval',
|
|
297
|
+
type: 'number',
|
|
298
|
+
default: 1000,
|
|
299
|
+
typeOptions: { minValue: 100, maxValue: 10000 },
|
|
300
|
+
description: 'Refresh interval in milliseconds (0 = WebSocket only)'
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
displayName: 'Show Task History',
|
|
304
|
+
name: 'showTaskHistory',
|
|
305
|
+
type: 'boolean',
|
|
306
|
+
default: true,
|
|
307
|
+
description: 'Display completed/failed tasks in history'
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
displayName: 'Show Messages',
|
|
311
|
+
name: 'showMessages',
|
|
312
|
+
type: 'boolean',
|
|
313
|
+
default: true,
|
|
314
|
+
description: 'Display inter-agent messages'
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
displayName: 'Max History Items',
|
|
318
|
+
name: 'maxHistoryItems',
|
|
319
|
+
type: 'number',
|
|
320
|
+
default: 50,
|
|
321
|
+
typeOptions: { minValue: 10, maxValue: 200 },
|
|
322
|
+
description: 'Maximum items to show in history'
|
|
323
|
+
}
|
|
324
|
+
]
|
|
281
325
|
}
|
|
282
326
|
};
|
|
283
327
|
|
|
284
|
-
export const UTILITY_NODE_TYPES = ['httpRequest', 'webhookTrigger', 'webhookResponse', 'chatTrigger', 'console'];
|
|
328
|
+
export const UTILITY_NODE_TYPES = ['httpRequest', 'webhookTrigger', 'webhookResponse', 'chatTrigger', 'console', 'teamMonitor'];
|
|
@@ -17,6 +17,7 @@ import { utilityNodes, UTILITY_NODE_TYPES } from './nodeDefinitions/utilityNodes
|
|
|
17
17
|
import { skillNodes, SKILL_NODE_TYPES } from './nodeDefinitions/skillNodes';
|
|
18
18
|
import { documentNodes, DOCUMENT_NODE_TYPES } from './nodeDefinitions/documentNodes';
|
|
19
19
|
import { socialNodes, SOCIAL_NODE_TYPES } from './nodeDefinitions/socialNodes';
|
|
20
|
+
import { twitterNodes, TWITTER_NODE_TYPES } from './nodeDefinitions/twitterNodes';
|
|
20
21
|
|
|
21
22
|
// ============================================================================
|
|
22
23
|
// MAIN NODE REGISTRY - Combining all modular definitions
|
|
@@ -38,7 +39,8 @@ export const nodeDefinitions: Record<string, INodeTypeDescription> = {
|
|
|
38
39
|
...utilityNodes,
|
|
39
40
|
...skillNodes,
|
|
40
41
|
...documentNodes,
|
|
41
|
-
...socialNodes
|
|
42
|
+
...socialNodes,
|
|
43
|
+
...twitterNodes
|
|
42
44
|
};
|
|
43
45
|
|
|
44
46
|
// ============================================================================
|
|
@@ -110,5 +112,9 @@ export const SOCIAL_NODES = [
|
|
|
110
112
|
...SOCIAL_NODE_TYPES
|
|
111
113
|
];
|
|
112
114
|
|
|
115
|
+
export const TWITTER_NODES = [
|
|
116
|
+
...TWITTER_NODE_TYPES
|
|
117
|
+
];
|
|
118
|
+
|
|
113
119
|
// Re-export types and utilities from modular files for external access
|
|
114
120
|
export { createBaseChatModel } from './nodeDefinitions/aiModelNodes';
|
|
@@ -5,6 +5,7 @@ import { CODE_NODE_TYPES } from '../nodeDefinitions/codeNodes';
|
|
|
5
5
|
import { UTILITY_NODE_TYPES } from '../nodeDefinitions/utilityNodes';
|
|
6
6
|
import { DOCUMENT_NODE_TYPES } from '../nodeDefinitions/documentNodes';
|
|
7
7
|
import { SPECIALIZED_AGENT_TYPES } from '../nodeDefinitions/specializedAgentNodes';
|
|
8
|
+
import { TWITTER_NODE_TYPES } from '../nodeDefinitions/twitterNodes';
|
|
8
9
|
import { Node, Edge } from 'reactflow';
|
|
9
10
|
import { INodeExecutionData } from '../types/INodeProperties';
|
|
10
11
|
import { API_CONFIG } from '../config/api';
|
|
@@ -223,7 +224,9 @@ export class ExecutionService {
|
|
|
223
224
|
// Utility Nodes (HTTP, Webhooks)
|
|
224
225
|
...UTILITY_NODE_TYPES,
|
|
225
226
|
// Document Processing Nodes
|
|
226
|
-
...DOCUMENT_NODE_TYPES
|
|
227
|
+
...DOCUMENT_NODE_TYPES,
|
|
228
|
+
// Twitter/X Nodes
|
|
229
|
+
...TWITTER_NODE_TYPES
|
|
227
230
|
];
|
|
228
231
|
|
|
229
232
|
return supportedTypes.includes(nodeType);
|
package/install.sh
CHANGED
|
@@ -52,11 +52,68 @@ detect_os() {
|
|
|
52
52
|
|
|
53
53
|
OS=$(detect_os)
|
|
54
54
|
|
|
55
|
+
# Detect WSL
|
|
56
|
+
is_wsl() {
|
|
57
|
+
[[ -n "$WSL_DISTRO_NAME" ]] || [[ -n "$WSL_INTEROP" ]] || grep -qi microsoft /proc/version 2>/dev/null
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
# Configure npm for WSL (fix nvm conflicts and Windows paths)
|
|
61
|
+
setup_wsl_npm() {
|
|
62
|
+
if ! is_wsl; then
|
|
63
|
+
return 0
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
info "WSL detected: Checking npm configuration..."
|
|
67
|
+
|
|
68
|
+
# If using nvm, remove any conflicting prefix from .npmrc
|
|
69
|
+
if [[ -n "$NVM_DIR" ]] || [[ -d "$HOME/.nvm" ]]; then
|
|
70
|
+
if grep -q '^prefix=' "$HOME/.npmrc" 2>/dev/null; then
|
|
71
|
+
info "Removing conflicting npm prefix (nvm detected)..."
|
|
72
|
+
sed -i '/^prefix=/d' "$HOME/.npmrc"
|
|
73
|
+
# Also remove globalconfig if present
|
|
74
|
+
sed -i '/^globalconfig=/d' "$HOME/.npmrc" 2>/dev/null || true
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
# Source nvm to ensure proper paths
|
|
78
|
+
export NVM_DIR="${NVM_DIR:-$HOME/.nvm}"
|
|
79
|
+
if [[ -s "$NVM_DIR/nvm.sh" ]]; then
|
|
80
|
+
source "$NVM_DIR/nvm.sh"
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
success "npm configured for nvm on WSL"
|
|
84
|
+
return 0
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
# No nvm - check if npm is using Windows path
|
|
88
|
+
local npm_prefix
|
|
89
|
+
npm_prefix=$(npm config get prefix 2>/dev/null || echo "")
|
|
90
|
+
|
|
91
|
+
if [[ "$npm_prefix" == /mnt/* ]]; then
|
|
92
|
+
info "Configuring npm to use Linux-native path..."
|
|
93
|
+
mkdir -p "$HOME/.npm-global"
|
|
94
|
+
npm config set prefix "$HOME/.npm-global"
|
|
95
|
+
export PATH="$HOME/.npm-global/bin:$PATH"
|
|
96
|
+
|
|
97
|
+
# Add to .bashrc if not already there
|
|
98
|
+
if ! grep -q 'npm-global' "$HOME/.bashrc" 2>/dev/null; then
|
|
99
|
+
echo '' >> "$HOME/.bashrc"
|
|
100
|
+
echo '# npm global packages (WSL)' >> "$HOME/.bashrc"
|
|
101
|
+
echo 'export PATH="$HOME/.npm-global/bin:$PATH"' >> "$HOME/.bashrc"
|
|
102
|
+
info "Added npm-global to PATH in ~/.bashrc"
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
success "npm configured for WSL"
|
|
106
|
+
fi
|
|
107
|
+
}
|
|
108
|
+
|
|
55
109
|
# =============================================================================
|
|
56
110
|
# Dependency Checks and Installation
|
|
57
111
|
# =============================================================================
|
|
58
112
|
|
|
59
113
|
check_node() {
|
|
114
|
+
# Clear command hash to ensure we find the latest node binary
|
|
115
|
+
hash -r 2>/dev/null || true
|
|
116
|
+
|
|
60
117
|
if command -v node &> /dev/null; then
|
|
61
118
|
version=$(node --version | tr -d 'v')
|
|
62
119
|
major=$(echo "$version" | cut -d. -f1)
|
|
@@ -76,6 +133,8 @@ install_node() {
|
|
|
76
133
|
macos)
|
|
77
134
|
if command -v brew &> /dev/null; then
|
|
78
135
|
brew install node@22
|
|
136
|
+
# Add node@22 to PATH (brew doesn't link it by default)
|
|
137
|
+
export PATH="/opt/homebrew/opt/node@22/bin:/usr/local/opt/node@22/bin:$PATH"
|
|
79
138
|
else
|
|
80
139
|
error_exit "Please install Homebrew first: https://brew.sh/"
|
|
81
140
|
fi
|
|
@@ -104,7 +163,7 @@ install_node() {
|
|
|
104
163
|
check_python() {
|
|
105
164
|
for cmd in python3 python; do
|
|
106
165
|
if command -v "$cmd" &> /dev/null; then
|
|
107
|
-
version=$($cmd --version 2>&1 |
|
|
166
|
+
version=$($cmd --version 2>&1 | sed -n 's/.*Python \([0-9]*\.[0-9]*\).*/\1/p')
|
|
108
167
|
major=$(echo "$version" | cut -d. -f1)
|
|
109
168
|
minor=$(echo "$version" | cut -d. -f2)
|
|
110
169
|
if [ "$major" -ge 3 ] && [ "$minor" -ge "$MIN_PYTHON_VERSION_MINOR" ]; then
|
|
@@ -192,6 +251,9 @@ main() {
|
|
|
192
251
|
check_python || install_python
|
|
193
252
|
check_uv || install_uv
|
|
194
253
|
|
|
254
|
+
# Configure npm for WSL before installing
|
|
255
|
+
setup_wsl_npm
|
|
256
|
+
|
|
195
257
|
echo ""
|
|
196
258
|
info "Installing MachinaOS..."
|
|
197
259
|
echo ""
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "machinaos",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.23",
|
|
4
4
|
"description": "Open source workflow automation platform with AI agents, React Flow, and n8n-inspired architecture",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"files": [
|
|
36
36
|
"bin/",
|
|
37
37
|
"scripts/",
|
|
38
|
+
"workflows/",
|
|
38
39
|
"client/src/",
|
|
39
40
|
"client/public/",
|
|
40
41
|
"client/dist/",
|
|
@@ -93,7 +94,9 @@
|
|
|
93
94
|
"daemon:restart": "node scripts/daemon.js restart",
|
|
94
95
|
"version:sync": "node scripts/sync-version.js",
|
|
95
96
|
"prepublishOnly": "node scripts/sync-version.js && node -e \"const p=require('./package.json'); if(!p.bin||!p.version){process.exit(1)}\"",
|
|
96
|
-
"
|
|
97
|
+
"preinstall": "node scripts/preinstall.js",
|
|
98
|
+
"postinstall": "node scripts/postinstall.js",
|
|
99
|
+
"preuninstall": "node scripts/preinstall.js"
|
|
97
100
|
},
|
|
98
101
|
"dependencies": {
|
|
99
102
|
"whatsapp-rpc": "^0.0.10",
|
package/scripts/build.js
CHANGED
|
File without changes
|
package/scripts/clean.js
CHANGED
|
File without changes
|
package/scripts/daemon.js
CHANGED
|
File without changes
|
package/scripts/docker.js
CHANGED
|
File without changes
|
package/scripts/install.js
CHANGED
|
File without changes
|