langflow-mcp-server 1.2.0 → 2.1.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.
Files changed (67) hide show
  1. package/.env.example +5 -0
  2. package/LICENSE +1 -1
  3. package/README.md +174 -3
  4. package/dist/__tests__/fixtures/advanced-execution.d.ts +22 -0
  5. package/dist/__tests__/fixtures/advanced-execution.d.ts.map +1 -0
  6. package/dist/__tests__/fixtures/advanced-execution.js +77 -0
  7. package/dist/__tests__/fixtures/advanced-execution.js.map +1 -0
  8. package/dist/__tests__/fixtures/api-keys.d.ts +8 -0
  9. package/dist/__tests__/fixtures/api-keys.d.ts.map +1 -0
  10. package/dist/__tests__/fixtures/api-keys.js +38 -0
  11. package/dist/__tests__/fixtures/api-keys.js.map +1 -0
  12. package/dist/__tests__/fixtures/auth.d.ts +9 -0
  13. package/dist/__tests__/fixtures/auth.d.ts.map +1 -0
  14. package/dist/__tests__/fixtures/auth.js +26 -0
  15. package/dist/__tests__/fixtures/auth.js.map +1 -0
  16. package/dist/__tests__/fixtures/custom-components.d.ts +5 -0
  17. package/dist/__tests__/fixtures/custom-components.d.ts.map +1 -0
  18. package/dist/__tests__/fixtures/custom-components.js +49 -0
  19. package/dist/__tests__/fixtures/custom-components.js.map +1 -0
  20. package/dist/__tests__/fixtures/files.d.ts +14 -0
  21. package/dist/__tests__/fixtures/files.d.ts.map +1 -0
  22. package/dist/__tests__/fixtures/files.js +41 -0
  23. package/dist/__tests__/fixtures/files.js.map +1 -0
  24. package/dist/__tests__/fixtures/misc.d.ts +18 -0
  25. package/dist/__tests__/fixtures/misc.d.ts.map +1 -0
  26. package/dist/__tests__/fixtures/misc.js +101 -0
  27. package/dist/__tests__/fixtures/misc.js.map +1 -0
  28. package/dist/__tests__/fixtures/monitoring.d.ts +13 -0
  29. package/dist/__tests__/fixtures/monitoring.d.ts.map +1 -0
  30. package/dist/__tests__/fixtures/monitoring.js +88 -0
  31. package/dist/__tests__/fixtures/monitoring.js.map +1 -0
  32. package/dist/__tests__/fixtures/store.d.ts +18 -0
  33. package/dist/__tests__/fixtures/store.d.ts.map +1 -0
  34. package/dist/__tests__/fixtures/store.js +96 -0
  35. package/dist/__tests__/fixtures/store.js.map +1 -0
  36. package/dist/__tests__/fixtures/users.d.ts +9 -0
  37. package/dist/__tests__/fixtures/users.d.ts.map +1 -0
  38. package/dist/__tests__/fixtures/users.js +55 -0
  39. package/dist/__tests__/fixtures/users.js.map +1 -0
  40. package/dist/__tests__/fixtures/validation.d.ts +10 -0
  41. package/dist/__tests__/fixtures/validation.d.ts.map +1 -0
  42. package/dist/__tests__/fixtures/validation.js +43 -0
  43. package/dist/__tests__/fixtures/validation.js.map +1 -0
  44. package/dist/__tests__/fixtures/vertices.d.ts +29 -0
  45. package/dist/__tests__/fixtures/vertices.d.ts.map +1 -0
  46. package/dist/__tests__/fixtures/vertices.js +51 -0
  47. package/dist/__tests__/fixtures/vertices.js.map +1 -0
  48. package/dist/mcp/index.js +0 -0
  49. package/dist/mcp/server.d.ts +2 -0
  50. package/dist/mcp/server.d.ts.map +1 -1
  51. package/dist/mcp/server.js +416 -9
  52. package/dist/mcp/server.js.map +1 -1
  53. package/dist/mcp/tools.d.ts.map +1 -1
  54. package/dist/mcp/tools.js +1218 -0
  55. package/dist/mcp/tools.js.map +1 -1
  56. package/dist/mcp/validation.d.ts +241 -0
  57. package/dist/mcp/validation.d.ts.map +1 -1
  58. package/dist/mcp/validation.js +213 -4
  59. package/dist/mcp/validation.js.map +1 -1
  60. package/dist/services/langflow-client.d.ts +131 -1
  61. package/dist/services/langflow-client.d.ts.map +1 -1
  62. package/dist/services/langflow-client.js +864 -18
  63. package/dist/services/langflow-client.js.map +1 -1
  64. package/dist/types/index.d.ts +226 -0
  65. package/dist/types/index.d.ts.map +1 -1
  66. package/healthcheck.js +41 -0
  67. package/package.json +6 -4
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.LangflowClient = void 0;
7
7
  const axios_1 = __importDefault(require("axios"));
8
+ const form_data_1 = __importDefault(require("form-data"));
8
9
  class LangflowClient {
9
10
  constructor(config) {
10
11
  this.config = config;
@@ -37,7 +38,7 @@ class LangflowClient {
37
38
  }
38
39
  async getFlow(flowId) {
39
40
  try {
40
- const response = await this.client.get(`/flows/${flowId}`);
41
+ const response = await this.client.get(`/flows/${encodeURIComponent(flowId)}`);
41
42
  return response.data;
42
43
  }
43
44
  catch (error) {
@@ -46,7 +47,7 @@ class LangflowClient {
46
47
  }
47
48
  async updateFlow(flowId, updates) {
48
49
  try {
49
- const response = await this.client.patch(`/flows/${flowId}`, updates);
50
+ const response = await this.client.patch(`/flows/${encodeURIComponent(flowId)}`, updates);
50
51
  return response.data;
51
52
  }
52
53
  catch (error) {
@@ -55,7 +56,7 @@ class LangflowClient {
55
56
  }
56
57
  async deleteFlow(flowId) {
57
58
  try {
58
- await this.client.delete(`/flows/${flowId}`);
59
+ await this.client.delete(`/flows/${encodeURIComponent(flowId)}`);
59
60
  }
60
61
  catch (error) {
61
62
  throw this.handleError(error, `Failed to delete flow ${flowId}`);
@@ -80,6 +81,9 @@ class LangflowClient {
80
81
  Object.entries(response.data).forEach(([category, items]) => {
81
82
  if (items && typeof items === 'object') {
82
83
  Object.entries(items).forEach(([name, info]) => {
84
+ if (!info || typeof info !== 'object') {
85
+ return;
86
+ }
83
87
  components.push({
84
88
  name,
85
89
  display_name: info.display_name || name,
@@ -98,7 +102,7 @@ class LangflowClient {
98
102
  }
99
103
  async runFlow(flowIdOrName, inputRequest, stream = false) {
100
104
  try {
101
- const response = await this.client.post(`/run/${flowIdOrName}`, {
105
+ const response = await this.client.post(`/run/${encodeURIComponent(flowIdOrName)}`, {
102
106
  ...inputRequest,
103
107
  stream
104
108
  });
@@ -110,7 +114,7 @@ class LangflowClient {
110
114
  }
111
115
  async triggerWebhook(flowIdOrName, inputRequest) {
112
116
  try {
113
- const response = await this.client.post(`/webhook/${flowIdOrName}`, inputRequest);
117
+ const response = await this.client.post(`/webhook/${encodeURIComponent(flowIdOrName)}`, inputRequest);
114
118
  return response.data;
115
119
  }
116
120
  catch (error) {
@@ -164,7 +168,7 @@ class LangflowClient {
164
168
  }
165
169
  async getFolder(folderId) {
166
170
  try {
167
- const response = await this.client.get(`/folders/${folderId}`);
171
+ const response = await this.client.get(`/folders/${encodeURIComponent(folderId)}`);
168
172
  return response.data;
169
173
  }
170
174
  catch (error) {
@@ -173,7 +177,7 @@ class LangflowClient {
173
177
  }
174
178
  async updateFolder(folderId, updates) {
175
179
  try {
176
- const response = await this.client.patch(`/folders/${folderId}`, updates);
180
+ const response = await this.client.patch(`/folders/${encodeURIComponent(folderId)}`, updates);
177
181
  return response.data;
178
182
  }
179
183
  catch (error) {
@@ -182,7 +186,7 @@ class LangflowClient {
182
186
  }
183
187
  async deleteFolder(folderId) {
184
188
  try {
185
- await this.client.delete(`/folders/${folderId}`);
189
+ await this.client.delete(`/folders/${encodeURIComponent(folderId)}`);
186
190
  }
187
191
  catch (error) {
188
192
  throw this.handleError(error, `Failed to delete folder ${folderId}`);
@@ -208,7 +212,7 @@ class LangflowClient {
208
212
  }
209
213
  async getProject(projectId) {
210
214
  try {
211
- const response = await this.client.get(`/projects/${projectId}`);
215
+ const response = await this.client.get(`/projects/${encodeURIComponent(projectId)}`);
212
216
  return response.data;
213
217
  }
214
218
  catch (error) {
@@ -217,7 +221,7 @@ class LangflowClient {
217
221
  }
218
222
  async updateProject(projectId, updates) {
219
223
  try {
220
- const response = await this.client.patch(`/projects/${projectId}`, updates);
224
+ const response = await this.client.patch(`/projects/${encodeURIComponent(projectId)}`, updates);
221
225
  return response.data;
222
226
  }
223
227
  catch (error) {
@@ -226,7 +230,7 @@ class LangflowClient {
226
230
  }
227
231
  async deleteProject(projectId) {
228
232
  try {
229
- await this.client.delete(`/projects/${projectId}`);
233
+ await this.client.delete(`/projects/${encodeURIComponent(projectId)}`);
230
234
  }
231
235
  catch (error) {
232
236
  throw this.handleError(error, `Failed to delete project ${projectId}`);
@@ -243,7 +247,7 @@ class LangflowClient {
243
247
  }
244
248
  async downloadProject(projectId) {
245
249
  try {
246
- const response = await this.client.get(`/projects/download/${projectId}`);
250
+ const response = await this.client.get(`/projects/download/${encodeURIComponent(projectId)}`);
247
251
  return response.data;
248
252
  }
249
253
  catch (error) {
@@ -270,7 +274,7 @@ class LangflowClient {
270
274
  }
271
275
  async updateVariable(variableId, updates) {
272
276
  try {
273
- const response = await this.client.patch(`/variables/${variableId}`, updates);
277
+ const response = await this.client.patch(`/variables/${encodeURIComponent(variableId)}`, updates);
274
278
  return response.data;
275
279
  }
276
280
  catch (error) {
@@ -279,7 +283,7 @@ class LangflowClient {
279
283
  }
280
284
  async deleteVariable(variableId) {
281
285
  try {
282
- await this.client.delete(`/variables/${variableId}`);
286
+ await this.client.delete(`/variables/${encodeURIComponent(variableId)}`);
283
287
  }
284
288
  catch (error) {
285
289
  throw this.handleError(error, `Failed to delete variable ${variableId}`);
@@ -287,7 +291,7 @@ class LangflowClient {
287
291
  }
288
292
  async buildFlow(flowId, request, params) {
289
293
  try {
290
- const response = await this.client.post(`/build/${flowId}/flow`, request, { params });
294
+ const response = await this.client.post(`/build/${encodeURIComponent(flowId)}/flow`, request, { params });
291
295
  return response.data;
292
296
  }
293
297
  catch (error) {
@@ -296,7 +300,7 @@ class LangflowClient {
296
300
  }
297
301
  async getBuildStatus(jobId, eventDelivery = 'polling') {
298
302
  try {
299
- const response = await this.client.get(`/build/${jobId}/events`, { params: { event_delivery: eventDelivery } });
303
+ const response = await this.client.get(`/build/${encodeURIComponent(jobId)}/events`, { params: { event_delivery: eventDelivery } });
300
304
  return response.data;
301
305
  }
302
306
  catch (error) {
@@ -305,7 +309,7 @@ class LangflowClient {
305
309
  }
306
310
  async cancelBuild(jobId) {
307
311
  try {
308
- const response = await this.client.post(`/build/${jobId}/cancel`);
312
+ const response = await this.client.post(`/build/${encodeURIComponent(jobId)}/cancel`);
309
313
  return response.data;
310
314
  }
311
315
  catch (error) {
@@ -349,6 +353,526 @@ class LangflowClient {
349
353
  throw this.handleError(error, 'Failed to bulk delete knowledge bases');
350
354
  }
351
355
  }
356
+ async uploadFile(params) {
357
+ try {
358
+ const formData = new form_data_1.default();
359
+ formData.append('file', params.file, params.file_name);
360
+ const response = await this.client.post(`/files/upload/${encodeURIComponent(params.flow_id)}`, formData, {
361
+ headers: {
362
+ ...formData.getHeaders()
363
+ }
364
+ });
365
+ return response.data;
366
+ }
367
+ catch (error) {
368
+ throw this.handleError(error, `Failed to upload file to flow ${params.flow_id}`);
369
+ }
370
+ }
371
+ async downloadFile(params) {
372
+ try {
373
+ const response = await this.client.get(`/files/download/${encodeURIComponent(params.flow_id)}/${encodeURIComponent(params.file_name)}`, {
374
+ responseType: 'arraybuffer'
375
+ });
376
+ return response.data;
377
+ }
378
+ catch (error) {
379
+ throw this.handleError(error, `Failed to download file ${params.file_name} from flow ${params.flow_id}`);
380
+ }
381
+ }
382
+ async listFiles(params) {
383
+ try {
384
+ const response = await this.client.get(`/files/list/${encodeURIComponent(params.flow_id)}`);
385
+ return response.data;
386
+ }
387
+ catch (error) {
388
+ throw this.handleError(error, `Failed to list files for flow ${params.flow_id}`);
389
+ }
390
+ }
391
+ async deleteFile(params) {
392
+ try {
393
+ const response = await this.client.delete(`/files/delete/${encodeURIComponent(params.flow_id)}/${encodeURIComponent(params.file_name)}`);
394
+ return response.data;
395
+ }
396
+ catch (error) {
397
+ throw this.handleError(error, `Failed to delete file ${params.file_name} from flow ${params.flow_id}`);
398
+ }
399
+ }
400
+ async getFileImage(params) {
401
+ try {
402
+ const response = await this.client.get(`/files/images/${encodeURIComponent(params.flow_id)}/${encodeURIComponent(params.file_name)}`, {
403
+ responseType: 'arraybuffer'
404
+ });
405
+ return response.data;
406
+ }
407
+ catch (error) {
408
+ throw this.handleError(error, `Failed to get image ${params.file_name} from flow ${params.flow_id}`);
409
+ }
410
+ }
411
+ async listProfilePictures() {
412
+ try {
413
+ const response = await this.client.get('/files/profile_pictures/list');
414
+ return response.data;
415
+ }
416
+ catch (error) {
417
+ throw this.handleError(error, 'Failed to list profile pictures');
418
+ }
419
+ }
420
+ async getProfilePicture(folderName, fileName) {
421
+ try {
422
+ const response = await this.client.get(`/files/profile_pictures/${folderName}/${fileName}`, {
423
+ responseType: 'arraybuffer'
424
+ });
425
+ return response.data;
426
+ }
427
+ catch (error) {
428
+ throw this.handleError(error, `Failed to get profile picture ${folderName}/${fileName}`);
429
+ }
430
+ }
431
+ async validateCode(code) {
432
+ try {
433
+ const response = await this.client.post('/validate/code', { code });
434
+ return response.data;
435
+ }
436
+ catch (error) {
437
+ throw this.handleError(error, 'Failed to validate code');
438
+ }
439
+ }
440
+ async validatePrompt(prompt) {
441
+ try {
442
+ const response = await this.client.post('/validate/prompt', { prompt });
443
+ return response.data;
444
+ }
445
+ catch (error) {
446
+ throw this.handleError(error, 'Failed to validate prompt');
447
+ }
448
+ }
449
+ async checkStore() {
450
+ try {
451
+ const response = await this.client.get('/store/check/');
452
+ return response.data;
453
+ }
454
+ catch (error) {
455
+ throw this.handleError(error, 'Failed to check store availability');
456
+ }
457
+ }
458
+ async checkStoreApiKey(apiKey) {
459
+ try {
460
+ const response = await this.client.get('/store/check/api_key', {
461
+ headers: {
462
+ 'x-store-api-key': apiKey
463
+ }
464
+ });
465
+ return response.data;
466
+ }
467
+ catch (error) {
468
+ throw this.handleError(error, 'Failed to check store API key');
469
+ }
470
+ }
471
+ async listStoreComponents(params) {
472
+ try {
473
+ const response = await this.client.get('/store/components/', { params });
474
+ return response.data;
475
+ }
476
+ catch (error) {
477
+ throw this.handleError(error, 'Failed to list store components');
478
+ }
479
+ }
480
+ async getStoreComponent(componentId) {
481
+ try {
482
+ const response = await this.client.get(`/store/components/${encodeURIComponent(componentId)}`);
483
+ return response.data;
484
+ }
485
+ catch (error) {
486
+ throw this.handleError(error, `Failed to get store component ${componentId}`);
487
+ }
488
+ }
489
+ async listStoreTags() {
490
+ try {
491
+ const response = await this.client.get('/store/tags');
492
+ return response.data;
493
+ }
494
+ catch (error) {
495
+ throw this.handleError(error, 'Failed to list store tags');
496
+ }
497
+ }
498
+ async getUserLikes() {
499
+ try {
500
+ const response = await this.client.get('/store/users/likes');
501
+ return response.data;
502
+ }
503
+ catch (error) {
504
+ throw this.handleError(error, 'Failed to get user likes');
505
+ }
506
+ }
507
+ async runFlowAdvanced(flowId, request, stream = false) {
508
+ try {
509
+ const response = await this.client.post(`/run/advanced/${encodeURIComponent(flowId)}`, {
510
+ ...request,
511
+ stream
512
+ });
513
+ return response.data;
514
+ }
515
+ catch (error) {
516
+ throw this.handleError(error, `Failed to run flow ${flowId} (advanced)`);
517
+ }
518
+ }
519
+ async processFlow(flowId, request) {
520
+ try {
521
+ const response = await this.client.post(`/process/${encodeURIComponent(flowId)}`, request);
522
+ return response.data;
523
+ }
524
+ catch (error) {
525
+ throw this.handleError(error, `Failed to process flow ${flowId}`);
526
+ }
527
+ }
528
+ async predictFlow(flowId, request) {
529
+ try {
530
+ const response = await this.client.post(`/predict/${encodeURIComponent(flowId)}`, request);
531
+ return response.data;
532
+ }
533
+ catch (error) {
534
+ throw this.handleError(error, `Failed to predict flow ${flowId}`);
535
+ }
536
+ }
537
+ async getMonitorBuilds(params) {
538
+ try {
539
+ const response = await this.client.get('/monitor/builds', { params });
540
+ return response.data;
541
+ }
542
+ catch (error) {
543
+ throw this.handleError(error, `Failed to get monitor builds for flow ${params.flow_id}`);
544
+ }
545
+ }
546
+ async getMonitorMessages(params) {
547
+ try {
548
+ const response = await this.client.get('/monitor/messages', { params });
549
+ return response.data;
550
+ }
551
+ catch (error) {
552
+ throw this.handleError(error, 'Failed to get monitor messages');
553
+ }
554
+ }
555
+ async getMonitorMessage(messageId) {
556
+ try {
557
+ const response = await this.client.get(`/monitor/messages/${encodeURIComponent(messageId)}`);
558
+ return response.data;
559
+ }
560
+ catch (error) {
561
+ throw this.handleError(error, `Failed to get monitor message ${messageId}`);
562
+ }
563
+ }
564
+ async getMonitorSessions(params) {
565
+ try {
566
+ const response = await this.client.get('/monitor/messages/sessions', { params });
567
+ return response.data;
568
+ }
569
+ catch (error) {
570
+ throw this.handleError(error, 'Failed to get monitor sessions');
571
+ }
572
+ }
573
+ async getMonitorSessionMessages(sessionId) {
574
+ try {
575
+ const response = await this.client.get(`/monitor/messages/session/${encodeURIComponent(sessionId)}`);
576
+ return response.data;
577
+ }
578
+ catch (error) {
579
+ throw this.handleError(error, `Failed to get session messages for ${sessionId}`);
580
+ }
581
+ }
582
+ async migrateMonitorSession(params) {
583
+ try {
584
+ const response = await this.client.patch(`/monitor/messages/session/${encodeURIComponent(params.old_session_id)}`, null, { params: { new_session_id: params.new_session_id } });
585
+ return response.data;
586
+ }
587
+ catch (error) {
588
+ throw this.handleError(error, `Failed to migrate session ${params.old_session_id}`);
589
+ }
590
+ }
591
+ async getMonitorTransactions(params) {
592
+ try {
593
+ const response = await this.client.get('/monitor/transactions', { params });
594
+ return response.data;
595
+ }
596
+ catch (error) {
597
+ throw this.handleError(error, 'Failed to get monitor transactions');
598
+ }
599
+ }
600
+ async deleteMonitorBuilds(flowId) {
601
+ try {
602
+ await this.client.delete('/monitor/builds', {
603
+ params: { flow_id: flowId }
604
+ });
605
+ }
606
+ catch (error) {
607
+ throw this.handleError(error, `Failed to delete monitor builds for flow ${flowId}`);
608
+ }
609
+ }
610
+ async deleteMonitorMessages(messageIds) {
611
+ try {
612
+ const response = await this.client.delete('/monitor/messages', { data: messageIds });
613
+ return response.data;
614
+ }
615
+ catch (error) {
616
+ throw this.handleError(error, 'Failed to delete monitor messages');
617
+ }
618
+ }
619
+ async buildVertices(flowId, request) {
620
+ try {
621
+ const response = await this.client.post(`/build/${encodeURIComponent(flowId)}/vertices`, {}, { params: request });
622
+ return response.data;
623
+ }
624
+ catch (error) {
625
+ throw this.handleError(error, `Failed to build vertices for flow ${flowId}`);
626
+ }
627
+ }
628
+ async getVertex(params) {
629
+ try {
630
+ const response = await this.client.get(`/build/${encodeURIComponent(params.flow_id)}/vertices/${encodeURIComponent(params.vertex_id)}`);
631
+ return response.data;
632
+ }
633
+ catch (error) {
634
+ throw this.handleError(error, `Failed to get vertex ${params.vertex_id}`);
635
+ }
636
+ }
637
+ async streamVertexBuild(params) {
638
+ try {
639
+ const response = await this.client.get(`/build/${encodeURIComponent(params.flow_id)}/${encodeURIComponent(params.vertex_id)}/stream`);
640
+ return response.data;
641
+ }
642
+ catch (error) {
643
+ throw this.handleError(error, `Failed to stream vertex build ${params.vertex_id}`);
644
+ }
645
+ }
646
+ async getVersion() {
647
+ try {
648
+ const response = await this.client.get('/version');
649
+ return response.data;
650
+ }
651
+ catch (error) {
652
+ throw this.handleError(error, 'Failed to get version');
653
+ }
654
+ }
655
+ async listUsers(params) {
656
+ try {
657
+ const response = await this.client.get('/users/', { params });
658
+ return response.data;
659
+ }
660
+ catch (error) {
661
+ throw this.handleError(error, 'Failed to list users');
662
+ }
663
+ }
664
+ async getCurrentUser() {
665
+ try {
666
+ const response = await this.client.get('/users/whoami');
667
+ return response.data;
668
+ }
669
+ catch (error) {
670
+ throw this.handleError(error, 'Failed to get current user');
671
+ }
672
+ }
673
+ async getUser(userId) {
674
+ try {
675
+ const response = await this.client.get(`/users/${encodeURIComponent(userId)}`);
676
+ return response.data;
677
+ }
678
+ catch (error) {
679
+ throw this.handleError(error, `Failed to get user ${userId}`);
680
+ }
681
+ }
682
+ async updateUser(userId, updates) {
683
+ try {
684
+ const response = await this.client.patch(`/users/${encodeURIComponent(userId)}`, updates);
685
+ return response.data;
686
+ }
687
+ catch (error) {
688
+ throw this.handleError(error, `Failed to update user ${userId}`);
689
+ }
690
+ }
691
+ async resetUserPassword(userId, newPassword) {
692
+ try {
693
+ const response = await this.client.patch(`/users/${userId}/reset-password`, {
694
+ password: newPassword
695
+ });
696
+ return response.data;
697
+ }
698
+ catch (error) {
699
+ throw this.handleError(error, `Failed to reset password for user ${userId}`);
700
+ }
701
+ }
702
+ async listApiKeys() {
703
+ try {
704
+ const response = await this.client.get('/api_key/');
705
+ return response.data;
706
+ }
707
+ catch (error) {
708
+ throw this.handleError(error, 'Failed to list API keys');
709
+ }
710
+ }
711
+ async createApiKey(name) {
712
+ try {
713
+ const response = await this.client.post('/api_key/', { name });
714
+ return response.data;
715
+ }
716
+ catch (error) {
717
+ throw this.handleError(error, 'Failed to create API key');
718
+ }
719
+ }
720
+ async deleteApiKey(apiKeyId) {
721
+ try {
722
+ await this.client.delete(`/api_key/${encodeURIComponent(apiKeyId)}`);
723
+ }
724
+ catch (error) {
725
+ throw this.handleError(error, `Failed to delete API key ${apiKeyId}`);
726
+ }
727
+ }
728
+ async listCustomComponents() {
729
+ try {
730
+ const response = await this.client.get('/custom_component');
731
+ return response.data;
732
+ }
733
+ catch (error) {
734
+ throw this.handleError(error, 'Failed to list custom components');
735
+ }
736
+ }
737
+ async createCustomComponent(component) {
738
+ try {
739
+ const response = await this.client.post('/custom_component', component);
740
+ return response.data;
741
+ }
742
+ catch (error) {
743
+ throw this.handleError(error, 'Failed to create custom component');
744
+ }
745
+ }
746
+ async login(username, password) {
747
+ try {
748
+ const formData = new URLSearchParams();
749
+ formData.append('username', username);
750
+ formData.append('password', password);
751
+ const response = await this.client.post('/login', formData, {
752
+ headers: {
753
+ 'Content-Type': 'application/x-www-form-urlencoded'
754
+ }
755
+ });
756
+ return response.data;
757
+ }
758
+ catch (error) {
759
+ throw this.handleError(error, 'Failed to login');
760
+ }
761
+ }
762
+ async autoLogin() {
763
+ try {
764
+ const response = await this.client.get('/auto_login');
765
+ return response.data;
766
+ }
767
+ catch (error) {
768
+ throw this.handleError(error, 'Failed to auto login');
769
+ }
770
+ }
771
+ async refreshToken() {
772
+ try {
773
+ const response = await this.client.post('/refresh');
774
+ return response.data;
775
+ }
776
+ catch (error) {
777
+ throw this.handleError(error, 'Failed to refresh token');
778
+ }
779
+ }
780
+ async logout() {
781
+ try {
782
+ const response = await this.client.post('/logout');
783
+ return response.data;
784
+ }
785
+ catch (error) {
786
+ throw this.handleError(error, 'Failed to logout');
787
+ }
788
+ }
789
+ async getPublicFlow(flowId) {
790
+ try {
791
+ const response = await this.client.get(`/flows/public_flow/${encodeURIComponent(flowId)}`);
792
+ return response.data;
793
+ }
794
+ catch (error) {
795
+ throw this.handleError(error, `Failed to get public flow ${flowId}`);
796
+ }
797
+ }
798
+ async batchCreateFlows(flows) {
799
+ try {
800
+ const response = await this.client.post('/flows/batch/', flows);
801
+ return response.data;
802
+ }
803
+ catch (error) {
804
+ throw this.handleError(error, 'Failed to batch create flows');
805
+ }
806
+ }
807
+ async getTaskStatus(taskId) {
808
+ try {
809
+ const response = await this.client.get(`/task/${encodeURIComponent(taskId)}`);
810
+ return response.data;
811
+ }
812
+ catch (error) {
813
+ throw this.handleError(error, `Failed to get task status ${taskId}`);
814
+ }
815
+ }
816
+ async downloadFolder(folderId) {
817
+ try {
818
+ const response = await this.client.get(`/folders/download/${folderId}`, {
819
+ responseType: 'arraybuffer'
820
+ });
821
+ return response.data;
822
+ }
823
+ catch (error) {
824
+ throw this.handleError(error, `Failed to download folder ${folderId}`);
825
+ }
826
+ }
827
+ async uploadFolder(fileContent, fileName) {
828
+ try {
829
+ const formData = new form_data_1.default();
830
+ formData.append('file', fileContent, fileName);
831
+ const response = await this.client.post('/folders/upload/', formData, {
832
+ headers: {
833
+ ...formData.getHeaders()
834
+ }
835
+ });
836
+ return response.data;
837
+ }
838
+ catch (error) {
839
+ throw this.handleError(error, 'Failed to upload folder');
840
+ }
841
+ }
842
+ async listStarterProjects() {
843
+ try {
844
+ const response = await this.client.get('/starter-projects/');
845
+ return response.data;
846
+ }
847
+ catch (error) {
848
+ throw this.handleError(error, 'Failed to list starter projects');
849
+ }
850
+ }
851
+ async uploadKnowledgeBase(kbName, fileContent, fileName) {
852
+ try {
853
+ const formData = new form_data_1.default();
854
+ formData.append('file', fileContent, fileName);
855
+ const response = await this.client.post('/knowledge_bases/', formData, {
856
+ params: { kb_name: kbName },
857
+ headers: {
858
+ ...formData.getHeaders()
859
+ }
860
+ });
861
+ return response.data;
862
+ }
863
+ catch (error) {
864
+ throw this.handleError(error, `Failed to upload knowledge base ${kbName}`);
865
+ }
866
+ }
867
+ async listElevenLabsVoices() {
868
+ try {
869
+ const response = await this.client.get('/voice/elevenlabs/voice_ids');
870
+ return response.data;
871
+ }
872
+ catch (error) {
873
+ throw this.handleError(error, 'Failed to list ElevenLabs voices');
874
+ }
875
+ }
352
876
  async healthCheck() {
353
877
  try {
354
878
  await this.client.get('/health');
@@ -358,12 +882,334 @@ class LangflowClient {
358
882
  return false;
359
883
  }
360
884
  }
885
+ async getLogs(stream = false) {
886
+ try {
887
+ const endpoint = stream ? '/logs-stream' : '/logs';
888
+ const response = await this.client.get(endpoint, {
889
+ responseType: stream ? 'stream' : 'json'
890
+ });
891
+ return response.data;
892
+ }
893
+ catch (error) {
894
+ throw this.handleError(error, 'Failed to get logs');
895
+ }
896
+ }
897
+ async getMonitorMessageById(messageId) {
898
+ try {
899
+ const response = await this.client.get(`/monitor/messages/${encodeURIComponent(messageId)}`);
900
+ return response.data;
901
+ }
902
+ catch (error) {
903
+ throw this.handleError(error, 'Failed to get monitor message');
904
+ }
905
+ }
906
+ async getMonitorTransactionById(transactionId) {
907
+ try {
908
+ const response = await this.client.get(`/monitor/transactions/${encodeURIComponent(transactionId)}`);
909
+ return response.data;
910
+ }
911
+ catch (error) {
912
+ throw this.handleError(error, 'Failed to get monitor transaction');
913
+ }
914
+ }
915
+ async getMonitorVertexBuilds(params) {
916
+ try {
917
+ const response = await this.client.get('/monitor/vertices/builds', { params });
918
+ return response.data;
919
+ }
920
+ catch (error) {
921
+ throw this.handleError(error, 'Failed to get monitor vertex builds');
922
+ }
923
+ }
924
+ async getMonitorVertexBuildById(vertexBuildId) {
925
+ try {
926
+ const response = await this.client.get(`/monitor/vertices/builds/${encodeURIComponent(vertexBuildId)}`);
927
+ return response.data;
928
+ }
929
+ catch (error) {
930
+ throw this.handleError(error, 'Failed to get monitor vertex build');
931
+ }
932
+ }
933
+ async uploadTextData(params) {
934
+ try {
935
+ const response = await this.client.post(`/files/upload/${encodeURIComponent(params.flow_id)}/text`, {
936
+ text: params.text_data,
937
+ file_name: params.file_name
938
+ });
939
+ return response.data;
940
+ }
941
+ catch (error) {
942
+ throw this.handleError(error, `Failed to upload text data to flow ${params.flow_id}`);
943
+ }
944
+ }
945
+ async installStoreComponent(componentId) {
946
+ try {
947
+ const response = await this.client.post(`/store/components/${componentId}/install`);
948
+ return response.data;
949
+ }
950
+ catch (error) {
951
+ throw this.handleError(error, `Failed to install store component ${componentId}`);
952
+ }
953
+ }
954
+ async updateCustomComponent(componentId, updates) {
955
+ try {
956
+ const response = await this.client.patch(`/custom_component/${encodeURIComponent(componentId)}`, updates);
957
+ return response.data;
958
+ }
959
+ catch (error) {
960
+ throw this.handleError(error, `Failed to update custom component ${componentId}`);
961
+ }
962
+ }
963
+ async deleteCustomComponent(componentId) {
964
+ try {
965
+ await this.client.delete(`/custom_component/${encodeURIComponent(componentId)}`);
966
+ }
967
+ catch (error) {
968
+ throw this.handleError(error, `Failed to delete custom component ${componentId}`);
969
+ }
970
+ }
971
+ async deleteUser(userId) {
972
+ try {
973
+ await this.client.delete(`/users/${encodeURIComponent(userId)}`);
974
+ }
975
+ catch (error) {
976
+ throw this.handleError(error, `Failed to delete user ${userId}`);
977
+ }
978
+ }
979
+ async getConfig() {
980
+ try {
981
+ const response = await this.client.get('/config');
982
+ return response.data;
983
+ }
984
+ catch (error) {
985
+ throw this.handleError(error, 'Failed to get configuration');
986
+ }
987
+ }
988
+ async updateConfig(config) {
989
+ try {
990
+ const response = await this.client.patch('/config', config);
991
+ return response.data;
992
+ }
993
+ catch (error) {
994
+ throw this.handleError(error, 'Failed to update configuration');
995
+ }
996
+ }
997
+ async getStats() {
998
+ try {
999
+ const response = await this.client.get('/stats');
1000
+ return response.data;
1001
+ }
1002
+ catch (error) {
1003
+ throw this.handleError(error, 'Failed to get statistics');
1004
+ }
1005
+ }
1006
+ async exportFlow(flowId) {
1007
+ try {
1008
+ const response = await this.client.get(`/flows/${encodeURIComponent(flowId)}/export`);
1009
+ return response.data;
1010
+ }
1011
+ catch (error) {
1012
+ throw this.handleError(error, `Failed to export flow ${flowId}`);
1013
+ }
1014
+ }
1015
+ async importFlow(flowData) {
1016
+ try {
1017
+ const response = await this.client.post('/flows/import', flowData);
1018
+ return response.data;
1019
+ }
1020
+ catch (error) {
1021
+ throw this.handleError(error, 'Failed to import flow');
1022
+ }
1023
+ }
1024
+ async cloneFlow(flowId, name) {
1025
+ try {
1026
+ const response = await this.client.post(`/flows/${encodeURIComponent(flowId)}/clone`, { name });
1027
+ return response.data;
1028
+ }
1029
+ catch (error) {
1030
+ throw this.handleError(error, `Failed to clone flow ${flowId}`);
1031
+ }
1032
+ }
1033
+ async getFlowDependencies(flowId) {
1034
+ try {
1035
+ const response = await this.client.get(`/flows/${encodeURIComponent(flowId)}/dependencies`);
1036
+ return response.data;
1037
+ }
1038
+ catch (error) {
1039
+ throw this.handleError(error, `Failed to get flow dependencies ${flowId}`);
1040
+ }
1041
+ }
1042
+ async getAiNodes() {
1043
+ try {
1044
+ const response = await this.client.get('/ai_nodes');
1045
+ return response.data;
1046
+ }
1047
+ catch (error) {
1048
+ throw this.handleError(error, 'Failed to get AI nodes');
1049
+ }
1050
+ }
1051
+ async buildVertex(params) {
1052
+ try {
1053
+ const response = await this.client.post(`/build/${encodeURIComponent(params.flow_id)}/vertices/${encodeURIComponent(params.vertex_id)}`, params.inputs || {});
1054
+ return response.data;
1055
+ }
1056
+ catch (error) {
1057
+ throw this.handleError(error, `Failed to build vertex ${params.vertex_id}`);
1058
+ }
1059
+ }
1060
+ async cancelExecution(params) {
1061
+ try {
1062
+ const response = await this.client.post(`/executions/${encodeURIComponent(params.execution_id)}/cancel`);
1063
+ return response.data;
1064
+ }
1065
+ catch (error) {
1066
+ throw this.handleError(error, `Failed to cancel execution ${params.execution_id}`);
1067
+ }
1068
+ }
1069
+ async getExecutionResult(params) {
1070
+ try {
1071
+ const response = await this.client.get(`/executions/${encodeURIComponent(params.execution_id)}/result`);
1072
+ return response.data;
1073
+ }
1074
+ catch (error) {
1075
+ throw this.handleError(error, `Failed to get execution result ${params.execution_id}`);
1076
+ }
1077
+ }
1078
+ async getFileMetadata(params) {
1079
+ try {
1080
+ const response = await this.client.get(`/files/${encodeURIComponent(params.flow_id)}/${encodeURIComponent(params.file_name)}/metadata`);
1081
+ return response.data;
1082
+ }
1083
+ catch (error) {
1084
+ throw this.handleError(error, `Failed to get file metadata ${params.file_name}`);
1085
+ }
1086
+ }
1087
+ async getHealth() {
1088
+ try {
1089
+ const response = await this.client.get('/health');
1090
+ return response.data;
1091
+ }
1092
+ catch (error) {
1093
+ throw this.handleError(error, 'Failed to get health status');
1094
+ }
1095
+ }
1096
+ async getUserById(userId) {
1097
+ try {
1098
+ const response = await this.client.get(`/users/${encodeURIComponent(userId)}`);
1099
+ return response.data;
1100
+ }
1101
+ catch (error) {
1102
+ throw this.handleError(error, `Failed to get user ${userId}`);
1103
+ }
1104
+ }
1105
+ async listFilesDetailed(params) {
1106
+ try {
1107
+ const response = await this.client.get(`/files/${encodeURIComponent(params.flow_id)}/detailed`);
1108
+ return response.data;
1109
+ }
1110
+ catch (error) {
1111
+ throw this.handleError(error, `Failed to get detailed file list for flow ${params.flow_id}`);
1112
+ }
1113
+ }
1114
+ async register(username, password, email) {
1115
+ try {
1116
+ const response = await this.client.post('/register', {
1117
+ username,
1118
+ password,
1119
+ email
1120
+ });
1121
+ return response.data;
1122
+ }
1123
+ catch (error) {
1124
+ throw this.handleError(error, 'Failed to register user');
1125
+ }
1126
+ }
1127
+ async runAdvancedExecution(params) {
1128
+ try {
1129
+ const { flow_id, ...request } = params;
1130
+ const response = await this.client.post(`/executions/${encodeURIComponent(flow_id)}/advanced`, request);
1131
+ return response.data;
1132
+ }
1133
+ catch (error) {
1134
+ throw this.handleError(error, `Failed to execute advanced flow ${params.flow_id}`);
1135
+ }
1136
+ }
1137
+ async searchStoreComponents(query, params) {
1138
+ try {
1139
+ const response = await this.client.get('/store/components/search', {
1140
+ params: { q: query, ...params }
1141
+ });
1142
+ return response.data;
1143
+ }
1144
+ catch (error) {
1145
+ throw this.handleError(error, 'Failed to search store components');
1146
+ }
1147
+ }
1148
+ async uninstallStoreComponent(componentId) {
1149
+ try {
1150
+ const response = await this.client.delete(`/store/components/${componentId}/uninstall`);
1151
+ return response.data;
1152
+ }
1153
+ catch (error) {
1154
+ throw this.handleError(error, `Failed to uninstall store component ${componentId}`);
1155
+ }
1156
+ }
1157
+ async updateStoreComponent(componentId, updates) {
1158
+ try {
1159
+ const response = await this.client.patch(`/store/components/${encodeURIComponent(componentId)}`, updates);
1160
+ return response.data;
1161
+ }
1162
+ catch (error) {
1163
+ throw this.handleError(error, `Failed to update store component ${componentId}`);
1164
+ }
1165
+ }
1166
+ async validateConnection(connectionData) {
1167
+ try {
1168
+ const response = await this.client.post('/validate/connection', connectionData);
1169
+ return response.data;
1170
+ }
1171
+ catch (error) {
1172
+ throw this.handleError(error, 'Failed to validate connection');
1173
+ }
1174
+ }
1175
+ async validateFlow(params) {
1176
+ try {
1177
+ const response = await this.client.post(`/flows/${encodeURIComponent(params.flow_id)}/validate`);
1178
+ return response.data;
1179
+ }
1180
+ catch (error) {
1181
+ throw this.handleError(error, `Failed to validate flow ${params.flow_id}`);
1182
+ }
1183
+ }
361
1184
  handleError(error, message) {
362
1185
  if (axios_1.default.isAxiosError(error)) {
363
1186
  const axiosError = error;
364
1187
  const status = axiosError.response?.status;
365
1188
  const data = axiosError.response?.data;
366
- return new Error(`${message}: ${status ? `HTTP ${status}` : 'Network error'} - ${data ? JSON.stringify(data) : axiosError.message}`);
1189
+ const sanitize = (val, depth = 0, seen = new WeakSet()) => {
1190
+ const MAX_DEPTH = 10;
1191
+ const SENSITIVE_KEYS = new Set([
1192
+ 'authorization', 'api_key', 'x-api-key', 'password', 'new_password', 'token',
1193
+ 'access_token', 'refresh_token', 'secret', 'api-key',
1194
+ 'bearer', 'private_key', 'session_id', 'cookie', 'set-cookie',
1195
+ 'x-store-api-key'
1196
+ ]);
1197
+ if (!val || typeof val !== 'object')
1198
+ return val;
1199
+ if (depth > MAX_DEPTH)
1200
+ return '[max depth exceeded]';
1201
+ if (Buffer.isBuffer(val) || val instanceof ArrayBuffer || ArrayBuffer.isView(val)) {
1202
+ return '[binary data]';
1203
+ }
1204
+ if (seen.has(val))
1205
+ return '[circular reference]';
1206
+ seen.add(val);
1207
+ if (Array.isArray(val))
1208
+ return val.map(v => sanitize(v, depth + 1, seen));
1209
+ return Object.fromEntries(Object.entries(val).map(([k, v]) => [k, SENSITIVE_KEYS.has(k.toLowerCase()) ? '***REDACTED***' : sanitize(v, depth + 1, seen)]));
1210
+ };
1211
+ const safeData = data ? sanitize(data) : undefined;
1212
+ return new Error(`${message}: ${status ? `HTTP ${status}` : 'Network error'} - ${safeData ? JSON.stringify(safeData) : axiosError.message}`);
367
1213
  }
368
1214
  if (error instanceof Error) {
369
1215
  return new Error(`${message}: ${error.message}`);