darabos commited on
Commit
2e080c7
·
unverified ·
2 Parent(s): 956034e c395e47

Merge pull request #228 from biggraph/darabos-mcp-example

Browse files
examples/LynxScribe/ChatAPI/Demo.lynxkite.json ADDED
@@ -0,0 +1,1230 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "edges": [
3
+ {
4
+ "id": "MCP: Search web 1 output Agent 1 tools",
5
+ "source": "MCP: Search web 1",
6
+ "sourceHandle": "output",
7
+ "target": "Agent 1",
8
+ "targetHandle": "tools"
9
+ },
10
+ {
11
+ "id": "Agent 1 output Agent 2 tools",
12
+ "source": "Agent 1",
13
+ "sourceHandle": "output",
14
+ "target": "Agent 2",
15
+ "targetHandle": "tools"
16
+ },
17
+ {
18
+ "id": "Database 1 output MCP: Query database with SQL 2 db",
19
+ "source": "Database 1",
20
+ "sourceHandle": "output",
21
+ "target": "MCP: Query database with SQL 2",
22
+ "targetHandle": "db"
23
+ },
24
+ {
25
+ "id": "MCP: Query database with SQL 2 output Agent 1 tools",
26
+ "source": "MCP: Query database with SQL 2",
27
+ "sourceHandle": "output",
28
+ "target": "Agent 1",
29
+ "targetHandle": "tools"
30
+ },
31
+ {
32
+ "id": "Agent 3 output Agent 2 tools",
33
+ "source": "Agent 3",
34
+ "sourceHandle": "output",
35
+ "target": "Agent 2",
36
+ "targetHandle": "tools"
37
+ },
38
+ {
39
+ "id": "MCP: Calculator 1 output Agent 1 tools",
40
+ "source": "MCP: Calculator 1",
41
+ "sourceHandle": "output",
42
+ "target": "Agent 1",
43
+ "targetHandle": "tools"
44
+ },
45
+ {
46
+ "id": "Agent 2 output Chat frontend 1 agent",
47
+ "source": "Agent 2",
48
+ "sourceHandle": "output",
49
+ "target": "Chat frontend 1",
50
+ "targetHandle": "agent"
51
+ },
52
+ {
53
+ "id": "Ladder graph 1 output PageRank 1 G",
54
+ "source": "Ladder graph 1",
55
+ "sourceHandle": "output",
56
+ "target": "PageRank 1",
57
+ "targetHandle": "G"
58
+ },
59
+ {
60
+ "id": "PageRank 1 output Database 1 data_pipeline",
61
+ "source": "PageRank 1",
62
+ "sourceHandle": "output",
63
+ "target": "Database 1",
64
+ "targetHandle": "data_pipeline"
65
+ },
66
+ {
67
+ "id": "Karate club graph 1 output Common neighbor centrality 1 G",
68
+ "source": "Karate club graph 1",
69
+ "sourceHandle": "output",
70
+ "target": "Common neighbor centrality 1",
71
+ "targetHandle": "G"
72
+ },
73
+ {
74
+ "id": "Common neighbor centrality 1 output Database 1 data_pipeline",
75
+ "source": "Common neighbor centrality 1",
76
+ "sourceHandle": "output",
77
+ "target": "Database 1",
78
+ "targetHandle": "data_pipeline"
79
+ },
80
+ {
81
+ "id": "Import file 1 output SQL 1 bundle",
82
+ "source": "Import file 1",
83
+ "sourceHandle": "output",
84
+ "target": "SQL 1",
85
+ "targetHandle": "bundle"
86
+ },
87
+ {
88
+ "id": "SQL 1 output SQL 2 bundle",
89
+ "source": "SQL 1",
90
+ "sourceHandle": "output",
91
+ "target": "SQL 2",
92
+ "targetHandle": "bundle"
93
+ },
94
+ {
95
+ "id": "SQL 2 output Database 1 data_pipeline",
96
+ "source": "SQL 2",
97
+ "sourceHandle": "output",
98
+ "target": "Database 1",
99
+ "targetHandle": "data_pipeline"
100
+ },
101
+ {
102
+ "id": "MCP: Run ComfyUI workflow 1 output Agent 3 tools",
103
+ "source": "MCP: Run ComfyUI workflow 1",
104
+ "sourceHandle": "output",
105
+ "target": "Agent 3",
106
+ "targetHandle": "tools"
107
+ }
108
+ ],
109
+ "env": "LynxKite Graph Analytics",
110
+ "nodes": [
111
+ {
112
+ "data": {
113
+ "collapsed": true,
114
+ "display": null,
115
+ "error": null,
116
+ "input_metadata": [
117
+ {}
118
+ ],
119
+ "meta": {
120
+ "categories": [
121
+ "Data Science"
122
+ ],
123
+ "color": "orange",
124
+ "doc": null,
125
+ "id": "Data Science > Database",
126
+ "inputs": [
127
+ {
128
+ "name": "data_pipeline",
129
+ "position": "left",
130
+ "type": {
131
+ "type": "list[lynxkite_graph_analytics.core.Bundle]"
132
+ }
133
+ }
134
+ ],
135
+ "name": "Database",
136
+ "outputs": [
137
+ {
138
+ "name": "output",
139
+ "position": "top",
140
+ "type": {
141
+ "type": "None"
142
+ }
143
+ }
144
+ ],
145
+ "params": [],
146
+ "type": "basic"
147
+ },
148
+ "op_id": "Data Science > Database",
149
+ "params": {},
150
+ "status": "done",
151
+ "title": "Database"
152
+ },
153
+ "dragHandle": ".drag-handle",
154
+ "height": 200.0,
155
+ "id": "Database 1",
156
+ "position": {
157
+ "x": -175.8708861292469,
158
+ "y": 465.47762360072204
159
+ },
160
+ "type": "basic",
161
+ "width": 200.0
162
+ },
163
+ {
164
+ "data": {
165
+ "__execution_delay": 0.0,
166
+ "display": null,
167
+ "error": null,
168
+ "input_metadata": [],
169
+ "meta": {
170
+ "categories": [
171
+ "LynxScribe"
172
+ ],
173
+ "color": "green",
174
+ "doc": null,
175
+ "id": "LynxScribe > MCP: Search web",
176
+ "inputs": [],
177
+ "name": "MCP: Search web",
178
+ "outputs": [
179
+ {
180
+ "name": "output",
181
+ "position": "top",
182
+ "type": {
183
+ "type": "None"
184
+ }
185
+ }
186
+ ],
187
+ "params": [
188
+ {
189
+ "default": "Google",
190
+ "name": "engine",
191
+ "type": {
192
+ "enum": [
193
+ "Google",
194
+ "Bing",
195
+ "DuckDuckGo"
196
+ ]
197
+ }
198
+ }
199
+ ],
200
+ "type": "basic"
201
+ },
202
+ "op_id": "LynxScribe > MCP: Search web",
203
+ "params": {
204
+ "engine": "Google"
205
+ },
206
+ "status": "done",
207
+ "title": "MCP: Search web"
208
+ },
209
+ "dragHandle": ".drag-handle",
210
+ "height": 156.0,
211
+ "id": "MCP: Search web 1",
212
+ "position": {
213
+ "x": 183.63527583294598,
214
+ "y": 221.47335161357154
215
+ },
216
+ "type": "basic",
217
+ "width": 204.0
218
+ },
219
+ {
220
+ "data": {
221
+ "__execution_delay": 0.0,
222
+ "display": null,
223
+ "error": null,
224
+ "input_metadata": [
225
+ {}
226
+ ],
227
+ "meta": {
228
+ "categories": [
229
+ "LynxScribe"
230
+ ],
231
+ "color": "blue",
232
+ "doc": null,
233
+ "id": "LynxScribe > Agent",
234
+ "inputs": [
235
+ {
236
+ "name": "tools",
237
+ "position": "bottom",
238
+ "type": {
239
+ "type": "list[str]"
240
+ }
241
+ }
242
+ ],
243
+ "name": "Agent",
244
+ "outputs": [
245
+ {
246
+ "name": "output",
247
+ "position": "top",
248
+ "type": {
249
+ "type": "None"
250
+ }
251
+ }
252
+ ],
253
+ "params": [
254
+ {
255
+ "default": "",
256
+ "name": "purpose",
257
+ "type": {
258
+ "type": "<class 'str'>"
259
+ }
260
+ },
261
+ {
262
+ "default": "This agent help with various tasks.",
263
+ "name": "description",
264
+ "type": {
265
+ "format": "textarea"
266
+ }
267
+ },
268
+ {
269
+ "default": "You are a helpful assistant.",
270
+ "name": "system_prompt",
271
+ "type": {
272
+ "format": "textarea"
273
+ }
274
+ }
275
+ ],
276
+ "type": "basic"
277
+ },
278
+ "op_id": "LynxScribe > Agent",
279
+ "params": {
280
+ "description": "This agent can help with data science\nand analytics questions.",
281
+ "purpose": "Data assistant",
282
+ "system_prompt": "Using the tools at your disposal answer\nall questions in JSON format."
283
+ },
284
+ "status": "done",
285
+ "title": "Agent"
286
+ },
287
+ "dragHandle": ".drag-handle",
288
+ "height": 351.0,
289
+ "id": "Agent 1",
290
+ "position": {
291
+ "x": -55.2832056082014,
292
+ "y": -263.46066732045733
293
+ },
294
+ "type": "basic",
295
+ "width": 337.0
296
+ },
297
+ {
298
+ "data": {
299
+ "__execution_delay": 0.0,
300
+ "display": null,
301
+ "error": null,
302
+ "input_metadata": [
303
+ {}
304
+ ],
305
+ "meta": {
306
+ "categories": [
307
+ "LynxScribe"
308
+ ],
309
+ "color": "blue",
310
+ "doc": null,
311
+ "id": "LynxScribe > Agent",
312
+ "inputs": [
313
+ {
314
+ "name": "tools",
315
+ "position": "bottom",
316
+ "type": {
317
+ "type": "list[str]"
318
+ }
319
+ }
320
+ ],
321
+ "name": "Agent",
322
+ "outputs": [
323
+ {
324
+ "name": "output",
325
+ "position": "top",
326
+ "type": {
327
+ "type": "None"
328
+ }
329
+ }
330
+ ],
331
+ "params": [
332
+ {
333
+ "default": "",
334
+ "name": "purpose",
335
+ "type": {
336
+ "type": "<class 'str'>"
337
+ }
338
+ },
339
+ {
340
+ "default": "This agent help with various tasks.",
341
+ "name": "description",
342
+ "type": {
343
+ "format": "textarea"
344
+ }
345
+ },
346
+ {
347
+ "default": "You are a helpful assistant.",
348
+ "name": "system_prompt",
349
+ "type": {
350
+ "format": "textarea"
351
+ }
352
+ }
353
+ ],
354
+ "type": "basic"
355
+ },
356
+ "op_id": "LynxScribe > Agent",
357
+ "params": {
358
+ "description": "",
359
+ "purpose": "Main conversation",
360
+ "system_prompt": "You are a helpful assistant. Use the agents at your disposal\nto help the user."
361
+ },
362
+ "status": "done",
363
+ "title": "Agent"
364
+ },
365
+ "dragHandle": ".drag-handle",
366
+ "height": 326.0,
367
+ "id": "Agent 2",
368
+ "position": {
369
+ "x": 226.41731551276598,
370
+ "y": -695.7509243963451
371
+ },
372
+ "type": "basic",
373
+ "width": 457.0
374
+ },
375
+ {
376
+ "data": {
377
+ "__execution_delay": 0.0,
378
+ "collapsed": true,
379
+ "display": null,
380
+ "error": null,
381
+ "input_metadata": [],
382
+ "meta": {
383
+ "categories": [
384
+ "NetworkX",
385
+ "Generators",
386
+ "Classic"
387
+ ],
388
+ "color": "orange",
389
+ "doc": null,
390
+ "id": "NetworkX > Generators > Classic > Ladder graph",
391
+ "inputs": [],
392
+ "name": "Ladder graph",
393
+ "outputs": [
394
+ {
395
+ "name": "output",
396
+ "position": "right",
397
+ "type": {
398
+ "type": "<class 'networkx.classes.graph.Graph'>"
399
+ }
400
+ }
401
+ ],
402
+ "params": [
403
+ {
404
+ "default": null,
405
+ "name": "n",
406
+ "type": {
407
+ "type": "<class 'int'>"
408
+ }
409
+ }
410
+ ],
411
+ "type": "basic"
412
+ },
413
+ "op_id": "NetworkX > Generators > Classic > Ladder graph",
414
+ "params": {
415
+ "n": "11"
416
+ },
417
+ "status": "done",
418
+ "title": "Ladder graph"
419
+ },
420
+ "dragHandle": ".drag-handle",
421
+ "height": 200.0,
422
+ "id": "Ladder graph 1",
423
+ "position": {
424
+ "x": -1297.4471345569843,
425
+ "y": 364.99969784589774
426
+ },
427
+ "type": "basic",
428
+ "width": 200.0
429
+ },
430
+ {
431
+ "data": {
432
+ "collapsed": true,
433
+ "display": null,
434
+ "error": null,
435
+ "input_metadata": [
436
+ {}
437
+ ],
438
+ "meta": {
439
+ "categories": [
440
+ "LynxScribe"
441
+ ],
442
+ "color": "green",
443
+ "doc": null,
444
+ "id": "LynxScribe > MCP: Query database with SQL",
445
+ "inputs": [
446
+ {
447
+ "name": "db",
448
+ "position": "bottom",
449
+ "type": {
450
+ "type": "<class 'str'>"
451
+ }
452
+ }
453
+ ],
454
+ "name": "MCP: Query database with SQL",
455
+ "outputs": [
456
+ {
457
+ "name": "output",
458
+ "position": "top",
459
+ "type": {
460
+ "type": "None"
461
+ }
462
+ }
463
+ ],
464
+ "params": [],
465
+ "type": "basic"
466
+ },
467
+ "op_id": "LynxScribe > MCP: Query database with SQL",
468
+ "params": {},
469
+ "status": "done",
470
+ "title": "MCP: Query database with SQL"
471
+ },
472
+ "dragHandle": ".drag-handle",
473
+ "height": 152.0,
474
+ "id": "MCP: Query database with SQL 2",
475
+ "position": {
476
+ "x": -248.451978071668,
477
+ "y": 231.5655840074671
478
+ },
479
+ "type": "basic",
480
+ "width": 334.0
481
+ },
482
+ {
483
+ "data": {
484
+ "__execution_delay": 0.0,
485
+ "display": null,
486
+ "error": null,
487
+ "input_metadata": [
488
+ {}
489
+ ],
490
+ "meta": {
491
+ "categories": [
492
+ "LynxScribe"
493
+ ],
494
+ "color": "blue",
495
+ "doc": null,
496
+ "id": "LynxScribe > Agent",
497
+ "inputs": [
498
+ {
499
+ "name": "tools",
500
+ "position": "bottom",
501
+ "type": {
502
+ "type": "list[str]"
503
+ }
504
+ }
505
+ ],
506
+ "name": "Agent",
507
+ "outputs": [
508
+ {
509
+ "name": "output",
510
+ "position": "top",
511
+ "type": {
512
+ "type": "None"
513
+ }
514
+ }
515
+ ],
516
+ "params": [
517
+ {
518
+ "default": "",
519
+ "name": "purpose",
520
+ "type": {
521
+ "type": "<class 'str'>"
522
+ }
523
+ },
524
+ {
525
+ "default": "This agent help with various tasks.",
526
+ "name": "description",
527
+ "type": {
528
+ "format": "textarea"
529
+ }
530
+ },
531
+ {
532
+ "default": "You are a helpful assistant.",
533
+ "name": "system_prompt",
534
+ "type": {
535
+ "format": "textarea"
536
+ }
537
+ }
538
+ ],
539
+ "type": "basic"
540
+ },
541
+ "op_id": "LynxScribe > Agent",
542
+ "params": {
543
+ "description": "This agent can help with\nimage generation tasks.",
544
+ "purpose": "Generate image",
545
+ "system_prompt": "Formulate a good image generation prompt\nand use the ComfyUI tool to generate\nan image according to the user's wishes."
546
+ },
547
+ "status": "done",
548
+ "title": "Agent"
549
+ },
550
+ "dragHandle": ".drag-handle",
551
+ "height": 392.0,
552
+ "id": "Agent 3",
553
+ "position": {
554
+ "x": 511.2723643375159,
555
+ "y": -276.6461006767206
556
+ },
557
+ "type": "basic",
558
+ "width": 368.0
559
+ },
560
+ {
561
+ "data": {
562
+ "collapsed": true,
563
+ "display": null,
564
+ "error": null,
565
+ "input_metadata": [],
566
+ "meta": {
567
+ "categories": [
568
+ "LynxScribe"
569
+ ],
570
+ "color": "green",
571
+ "doc": null,
572
+ "id": "LynxScribe > MCP: Calculator",
573
+ "inputs": [],
574
+ "name": "MCP: Calculator",
575
+ "outputs": [
576
+ {
577
+ "name": "output",
578
+ "position": "top",
579
+ "type": {
580
+ "type": "None"
581
+ }
582
+ }
583
+ ],
584
+ "params": [],
585
+ "type": "basic"
586
+ },
587
+ "op_id": "LynxScribe > MCP: Calculator",
588
+ "params": {},
589
+ "status": "done",
590
+ "title": "MCP: Calculator"
591
+ },
592
+ "dragHandle": ".drag-handle",
593
+ "height": 200.0,
594
+ "id": "MCP: Calculator 1",
595
+ "position": {
596
+ "x": -527.6679408294542,
597
+ "y": 240.503939070944
598
+ },
599
+ "type": "basic",
600
+ "width": 200.0
601
+ },
602
+ {
603
+ "data": {
604
+ "collapsed": false,
605
+ "display": {
606
+ "dataframes": {
607
+ "service": {
608
+ "columns": [
609
+ "url"
610
+ ],
611
+ "data": [
612
+ [
613
+ "/api/service/lynxkite_graph_analytics/LynxScribe MCP/Demo.lynxkite.json/Chat frontend 1"
614
+ ]
615
+ ]
616
+ }
617
+ }
618
+ },
619
+ "error": null,
620
+ "input_metadata": [
621
+ {}
622
+ ],
623
+ "meta": {
624
+ "categories": [
625
+ "LynxScribe"
626
+ ],
627
+ "color": "gray",
628
+ "doc": null,
629
+ "id": "LynxScribe > Chat frontend",
630
+ "inputs": [
631
+ {
632
+ "name": "agent",
633
+ "position": "bottom",
634
+ "type": {
635
+ "type": "<class 'str'>"
636
+ }
637
+ }
638
+ ],
639
+ "name": "Chat frontend",
640
+ "outputs": [],
641
+ "params": [],
642
+ "type": "service"
643
+ },
644
+ "op_id": "LynxScribe > Chat frontend",
645
+ "params": {},
646
+ "status": "done",
647
+ "title": "Chat frontend"
648
+ },
649
+ "dragHandle": ".drag-handle",
650
+ "height": 362.0,
651
+ "id": "Chat frontend 1",
652
+ "position": {
653
+ "x": 237.184571561771,
654
+ "y": -1107.6739000139528
655
+ },
656
+ "type": "service",
657
+ "width": 428.0
658
+ },
659
+ {
660
+ "data": {
661
+ "collapsed": true,
662
+ "display": null,
663
+ "error": null,
664
+ "input_metadata": [
665
+ {}
666
+ ],
667
+ "meta": {
668
+ "categories": [
669
+ "NetworkX",
670
+ "Algorithms",
671
+ "Link analysis",
672
+ "PageRank alg"
673
+ ],
674
+ "color": "orange",
675
+ "doc": null,
676
+ "id": "NetworkX > Algorithms > Link analysis > PageRank alg > PageRank",
677
+ "inputs": [
678
+ {
679
+ "name": "G",
680
+ "position": "left",
681
+ "type": {
682
+ "type": "<class 'networkx.classes.graph.Graph'>"
683
+ }
684
+ }
685
+ ],
686
+ "name": "PageRank",
687
+ "outputs": [
688
+ {
689
+ "name": "output",
690
+ "position": "right",
691
+ "type": {
692
+ "type": "<class 'networkx.classes.graph.Graph'>"
693
+ }
694
+ }
695
+ ],
696
+ "params": [
697
+ {
698
+ "default": "0.85",
699
+ "name": "alpha",
700
+ "type": {
701
+ "type": "float | None"
702
+ }
703
+ },
704
+ {
705
+ "default": "100",
706
+ "name": "max_iter",
707
+ "type": {
708
+ "type": "int | None"
709
+ }
710
+ },
711
+ {
712
+ "default": "1e-06",
713
+ "name": "tol",
714
+ "type": {
715
+ "type": "float | None"
716
+ }
717
+ },
718
+ {
719
+ "default": "weight",
720
+ "name": "weight",
721
+ "type": {
722
+ "type": "str | None"
723
+ }
724
+ }
725
+ ],
726
+ "type": "basic"
727
+ },
728
+ "op_id": "NetworkX > Algorithms > Link analysis > PageRank alg > PageRank",
729
+ "params": {
730
+ "alpha": "0.85",
731
+ "max_iter": "100",
732
+ "tol": "1e-06",
733
+ "weight": "weight"
734
+ },
735
+ "status": "done",
736
+ "title": "PageRank"
737
+ },
738
+ "dragHandle": ".drag-handle",
739
+ "height": 200.0,
740
+ "id": "PageRank 1",
741
+ "position": {
742
+ "x": -878.5796659405156,
743
+ "y": 369.96445264090244
744
+ },
745
+ "type": "basic",
746
+ "width": 200.0
747
+ },
748
+ {
749
+ "data": {
750
+ "collapsed": true,
751
+ "display": null,
752
+ "error": null,
753
+ "input_metadata": [],
754
+ "meta": {
755
+ "categories": [
756
+ "NetworkX",
757
+ "Generators",
758
+ "Social"
759
+ ],
760
+ "color": "orange",
761
+ "doc": null,
762
+ "id": "NetworkX > Generators > Social > Karate club graph",
763
+ "inputs": [],
764
+ "name": "Karate club graph",
765
+ "outputs": [
766
+ {
767
+ "name": "output",
768
+ "position": "right",
769
+ "type": {
770
+ "type": "<class 'networkx.classes.graph.Graph'>"
771
+ }
772
+ }
773
+ ],
774
+ "params": [],
775
+ "type": "basic"
776
+ },
777
+ "op_id": "NetworkX > Generators > Social > Karate club graph",
778
+ "params": {},
779
+ "status": "done",
780
+ "title": "Karate club graph"
781
+ },
782
+ "dragHandle": ".drag-handle",
783
+ "height": 200.0,
784
+ "id": "Karate club graph 1",
785
+ "position": {
786
+ "x": -1304.6391517192224,
787
+ "y": 585.0242219568652
788
+ },
789
+ "type": "basic",
790
+ "width": 200.0
791
+ },
792
+ {
793
+ "data": {
794
+ "collapsed": true,
795
+ "display": null,
796
+ "error": null,
797
+ "input_metadata": [
798
+ {}
799
+ ],
800
+ "meta": {
801
+ "categories": [
802
+ "NetworkX",
803
+ "Algorithms",
804
+ "Link prediction"
805
+ ],
806
+ "color": "orange",
807
+ "doc": null,
808
+ "id": "NetworkX > Algorithms > Link prediction > Common neighbor centrality",
809
+ "inputs": [
810
+ {
811
+ "name": "G",
812
+ "position": "left",
813
+ "type": {
814
+ "type": "<class 'networkx.classes.graph.Graph'>"
815
+ }
816
+ }
817
+ ],
818
+ "name": "Common neighbor centrality",
819
+ "outputs": [
820
+ {
821
+ "name": "output",
822
+ "position": "right",
823
+ "type": {
824
+ "type": "<class 'networkx.classes.graph.Graph'>"
825
+ }
826
+ }
827
+ ],
828
+ "params": [],
829
+ "type": "basic"
830
+ },
831
+ "op_id": "NetworkX > Algorithms > Link prediction > Common neighbor centrality",
832
+ "params": {},
833
+ "status": "done",
834
+ "title": "Common neighbor centrality"
835
+ },
836
+ "dragHandle": ".drag-handle",
837
+ "height": 130.0,
838
+ "id": "Common neighbor centrality 1",
839
+ "position": {
840
+ "x": -990.2453153930347,
841
+ "y": 587.3192401780905
842
+ },
843
+ "type": "basic",
844
+ "width": 341.0
845
+ },
846
+ {
847
+ "data": {
848
+ "__execution_delay": 0.0,
849
+ "collapsed": true,
850
+ "display": null,
851
+ "error": null,
852
+ "input_metadata": [],
853
+ "meta": {
854
+ "categories": [],
855
+ "color": "orange",
856
+ "doc": [
857
+ {
858
+ "kind": "text",
859
+ "value": "Read the contents of the a file into a `Bundle`."
860
+ },
861
+ {
862
+ "kind": "parameters",
863
+ "value": [
864
+ {
865
+ "annotation": "str",
866
+ "description": "Path to the file to import.",
867
+ "name": "file_path"
868
+ },
869
+ {
870
+ "annotation": "str",
871
+ "description": "Name to use for identifying the table in the bundle.",
872
+ "name": "table_name"
873
+ },
874
+ {
875
+ "annotation": "FileFormat",
876
+ "description": "Format of the file. Has to be one of the values in the `FileFormat` enum.",
877
+ "name": "file_format"
878
+ }
879
+ ]
880
+ },
881
+ {
882
+ "kind": "returns",
883
+ "value": [
884
+ {
885
+ "annotation": "<class 'lynxkite_graph_analytics.core.Bundle'>",
886
+ "description": "Bundle with a single table with the contents of the file.",
887
+ "name": "Bundle"
888
+ }
889
+ ]
890
+ }
891
+ ],
892
+ "id": "Import file",
893
+ "inputs": [],
894
+ "name": "Import file",
895
+ "outputs": [
896
+ {
897
+ "name": "output",
898
+ "position": "right",
899
+ "type": {
900
+ "type": "None"
901
+ }
902
+ }
903
+ ],
904
+ "params": [
905
+ {
906
+ "default": null,
907
+ "name": "file_path",
908
+ "type": {
909
+ "type": "<class 'str'>"
910
+ }
911
+ },
912
+ {
913
+ "default": null,
914
+ "name": "table_name",
915
+ "type": {
916
+ "type": "<class 'str'>"
917
+ }
918
+ },
919
+ {
920
+ "default": "csv",
921
+ "name": "file_format",
922
+ "type": {
923
+ "enum": [
924
+ "csv",
925
+ "parquet",
926
+ "json",
927
+ "excel"
928
+ ]
929
+ }
930
+ },
931
+ {
932
+ "default": "csv",
933
+ "groups": {
934
+ "csv": [
935
+ {
936
+ "default": "<from file>",
937
+ "name": "columns",
938
+ "type": {
939
+ "type": "<class 'str'>"
940
+ }
941
+ },
942
+ {
943
+ "default": "<auto>",
944
+ "name": "separator",
945
+ "type": {
946
+ "type": "<class 'str'>"
947
+ }
948
+ }
949
+ ],
950
+ "excel": [
951
+ {
952
+ "default": "Sheet1",
953
+ "name": "sheet_name",
954
+ "type": {
955
+ "type": "<class 'str'>"
956
+ }
957
+ }
958
+ ],
959
+ "json": [],
960
+ "parquet": []
961
+ },
962
+ "name": "file_format_group",
963
+ "selector": {
964
+ "default": "csv",
965
+ "name": "file_format",
966
+ "type": {
967
+ "enum": [
968
+ "csv",
969
+ "parquet",
970
+ "json",
971
+ "excel"
972
+ ]
973
+ }
974
+ },
975
+ "type": "group"
976
+ }
977
+ ],
978
+ "type": "basic"
979
+ },
980
+ "op_id": "Import file",
981
+ "params": {
982
+ "file_format": "csv",
983
+ "file_format_group": "csv",
984
+ "file_path": "uploads/molecules2.csv",
985
+ "table_name": "molecules"
986
+ },
987
+ "status": "done",
988
+ "title": "Import file"
989
+ },
990
+ "dragHandle": ".drag-handle",
991
+ "height": 393.0,
992
+ "id": "Import file 1",
993
+ "position": {
994
+ "x": -1411.4491034838866,
995
+ "y": 772.1675932822765
996
+ },
997
+ "type": "basic",
998
+ "width": 369.0
999
+ },
1000
+ {
1001
+ "data": {
1002
+ "__execution_delay": 0.0,
1003
+ "collapsed": true,
1004
+ "display": null,
1005
+ "error": null,
1006
+ "input_metadata": [
1007
+ {
1008
+ "dataframes": {
1009
+ "molecules": {
1010
+ "columns": [
1011
+ "name",
1012
+ "smiles"
1013
+ ],
1014
+ "key": "molecules"
1015
+ }
1016
+ },
1017
+ "other": {},
1018
+ "relations": []
1019
+ }
1020
+ ],
1021
+ "meta": {
1022
+ "categories": [],
1023
+ "color": "orange",
1024
+ "doc": [
1025
+ {
1026
+ "kind": "text",
1027
+ "value": "Run a SQL query on the DataFrames in the bundle. Save the results as a new DataFrame."
1028
+ }
1029
+ ],
1030
+ "id": "SQL",
1031
+ "inputs": [
1032
+ {
1033
+ "name": "bundle",
1034
+ "position": "left",
1035
+ "type": {
1036
+ "type": "<class 'lynxkite_graph_analytics.core.Bundle'>"
1037
+ }
1038
+ }
1039
+ ],
1040
+ "name": "SQL",
1041
+ "outputs": [
1042
+ {
1043
+ "name": "output",
1044
+ "position": "right",
1045
+ "type": {
1046
+ "type": "None"
1047
+ }
1048
+ }
1049
+ ],
1050
+ "params": [
1051
+ {
1052
+ "default": null,
1053
+ "name": "query",
1054
+ "type": {
1055
+ "format": "textarea"
1056
+ }
1057
+ },
1058
+ {
1059
+ "default": "result",
1060
+ "name": "save_as",
1061
+ "type": {
1062
+ "type": "<class 'str'>"
1063
+ }
1064
+ }
1065
+ ],
1066
+ "type": "basic"
1067
+ },
1068
+ "op_id": "SQL",
1069
+ "params": {
1070
+ "query": "select *",
1071
+ "save_as": "result"
1072
+ },
1073
+ "status": "done",
1074
+ "title": "SQL"
1075
+ },
1076
+ "dragHandle": ".drag-handle",
1077
+ "height": 200.0,
1078
+ "id": "SQL 1",
1079
+ "position": {
1080
+ "x": -931.2061769202694,
1081
+ "y": 766.0054007337461
1082
+ },
1083
+ "type": "basic",
1084
+ "width": 200.0
1085
+ },
1086
+ {
1087
+ "data": {
1088
+ "__execution_delay": 0.0,
1089
+ "collapsed": true,
1090
+ "display": null,
1091
+ "error": null,
1092
+ "input_metadata": [
1093
+ {
1094
+ "dataframes": {
1095
+ "molecules": {
1096
+ "columns": [
1097
+ "name",
1098
+ "smiles"
1099
+ ],
1100
+ "key": "molecules"
1101
+ },
1102
+ "result": {
1103
+ "columns": [],
1104
+ "key": "result"
1105
+ }
1106
+ },
1107
+ "other": {},
1108
+ "relations": []
1109
+ }
1110
+ ],
1111
+ "meta": {
1112
+ "categories": [],
1113
+ "color": "orange",
1114
+ "doc": [
1115
+ {
1116
+ "kind": "text",
1117
+ "value": "Run a SQL query on the DataFrames in the bundle. Save the results as a new DataFrame."
1118
+ }
1119
+ ],
1120
+ "id": "SQL",
1121
+ "inputs": [
1122
+ {
1123
+ "name": "bundle",
1124
+ "position": "left",
1125
+ "type": {
1126
+ "type": "<class 'lynxkite_graph_analytics.core.Bundle'>"
1127
+ }
1128
+ }
1129
+ ],
1130
+ "name": "SQL",
1131
+ "outputs": [
1132
+ {
1133
+ "name": "output",
1134
+ "position": "right",
1135
+ "type": {
1136
+ "type": "None"
1137
+ }
1138
+ }
1139
+ ],
1140
+ "params": [
1141
+ {
1142
+ "default": null,
1143
+ "name": "query",
1144
+ "type": {
1145
+ "format": "textarea"
1146
+ }
1147
+ },
1148
+ {
1149
+ "default": "result",
1150
+ "name": "save_as",
1151
+ "type": {
1152
+ "type": "<class 'str'>"
1153
+ }
1154
+ }
1155
+ ],
1156
+ "type": "basic"
1157
+ },
1158
+ "op_id": "SQL",
1159
+ "params": {
1160
+ "query": "select *",
1161
+ "save_as": "result"
1162
+ },
1163
+ "status": "done",
1164
+ "title": "SQL"
1165
+ },
1166
+ "dragHandle": ".drag-handle",
1167
+ "height": 200.0,
1168
+ "id": "SQL 2",
1169
+ "position": {
1170
+ "x": -633.7783633982368,
1171
+ "y": 767.4541281209835
1172
+ },
1173
+ "type": "basic",
1174
+ "width": 200.0
1175
+ },
1176
+ {
1177
+ "data": {
1178
+ "__execution_delay": 0.0,
1179
+ "display": null,
1180
+ "error": null,
1181
+ "input_metadata": [],
1182
+ "meta": {
1183
+ "categories": [
1184
+ "LynxScribe"
1185
+ ],
1186
+ "color": "green",
1187
+ "doc": null,
1188
+ "id": "LynxScribe > MCP: Run ComfyUI workflow",
1189
+ "inputs": [],
1190
+ "name": "MCP: Run ComfyUI workflow",
1191
+ "outputs": [
1192
+ {
1193
+ "name": "output",
1194
+ "position": "top",
1195
+ "type": {
1196
+ "type": "None"
1197
+ }
1198
+ }
1199
+ ],
1200
+ "params": [
1201
+ {
1202
+ "default": null,
1203
+ "name": "workflow_name",
1204
+ "type": {
1205
+ "type": "<class 'str'>"
1206
+ }
1207
+ }
1208
+ ],
1209
+ "type": "basic"
1210
+ },
1211
+ "op_id": "LynxScribe > MCP: Run ComfyUI workflow",
1212
+ "params": {
1213
+ "workflow_name": "SDXL"
1214
+ },
1215
+ "status": "done",
1216
+ "title": "MCP: Run ComfyUI workflow"
1217
+ },
1218
+ "dragHandle": ".drag-handle",
1219
+ "height": 200.0,
1220
+ "id": "MCP: Run ComfyUI workflow 1",
1221
+ "position": {
1222
+ "x": 598.9560131686237,
1223
+ "y": 218.52928063566645
1224
+ },
1225
+ "type": "basic",
1226
+ "width": 200.0
1227
+ }
1228
+ ],
1229
+ "paused": false
1230
+ }
examples/LynxScribe/ChatAPI/demo.py ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import enum
2
+ from lynxkite_core import ops
3
+ from lynxkite_graph_analytics import core
4
+ import fastapi
5
+ from lynxscribe.components.chat.api import ChatAPI
6
+ from lynxscribe.components.rag.rag_chatbot import Mode, RAGChatbot, Scenario, ScenarioSelector
7
+ from lynxscribe.core.llm.base import get_llm_engine
8
+ from lynxscribe.core.models.prompts import ChatCompletionPrompt
9
+
10
+ lsop = ops.op_registration(
11
+ "LynxKite Graph Analytics", "LynxScribe", dir="bottom-to-top", color="blue"
12
+ )
13
+
14
+ dsop = ops.op_registration("LynxKite Graph Analytics", "Data Science")
15
+
16
+ Placeholder = str
17
+
18
+
19
+ @lsop("Chat frontend", color="gray", outputs=[], view="service")
20
+ def chat_frontend(agent: Placeholder):
21
+ return ChatAPIService(agent)
22
+
23
+
24
+ @lsop("Agent")
25
+ def agent(
26
+ tools: list[Placeholder],
27
+ *,
28
+ purpose: str = "",
29
+ description: ops.LongStr = "This agent helps with various tasks.",
30
+ system_prompt: ops.LongStr = "You are a helpful assistant.",
31
+ ):
32
+ ts = []
33
+ for t in tools:
34
+ t = "\n ".join(t.split("\n"))
35
+ ts.append(f"- {t}\n")
36
+ return f"Agent for {purpose} with {len(tools)} tools:\n{''.join(ts)}"
37
+
38
+
39
+ @lsop("MCP: Query database with SQL", color="green")
40
+ def sql_tool(db: Placeholder):
41
+ return f"SQL over {db}"
42
+
43
+
44
+ @ops.output_position(output="top")
45
+ @dsop("Database")
46
+ def db(data_pipeline: list[core.Bundle]):
47
+ return f"DB with {len(data_pipeline)} bundles"
48
+
49
+
50
+ class MCPSearchEngine(str, enum.Enum):
51
+ Google = "Google"
52
+ Bing = "Bing"
53
+ DuckDuckGo = "DuckDuckGo"
54
+
55
+
56
+ @lsop("MCP: Search web", color="green")
57
+ def web_search(*, engine: MCPSearchEngine = MCPSearchEngine.Google):
58
+ return f"Web search ({engine.name})"
59
+
60
+
61
+ @lsop("MCP: Run ComfyUI workflow", color="green")
62
+ def run_comfyui_workflow(*, workflow_name: str):
63
+ return f"Run comfyui workflow ({workflow_name})"
64
+
65
+
66
+ @lsop("MCP: Calculator", color="green")
67
+ def calculator():
68
+ return "Calculator"
69
+
70
+
71
+ class ChatAPIService:
72
+ def __init__(self, agent: str):
73
+ self.agent = agent
74
+ self.chat_api = ChatAPI(
75
+ chatbot=RAGChatbot(
76
+ None,
77
+ ScenarioSelector([Scenario(name="single", mode=Mode.LLM_ONLY)]),
78
+ llm=get_llm_engine(name="openai"),
79
+ ),
80
+ model="gpt-4o-mini",
81
+ )
82
+
83
+ async def get(self, request: fastapi.Request) -> dict:
84
+ if request.state.remaining_path == "models":
85
+ return {
86
+ "object": "list",
87
+ "data": [
88
+ {
89
+ "id": "LynxScribe",
90
+ "object": "model",
91
+ "created": 0,
92
+ "owned_by": "lynxkite",
93
+ "meta": {"profile_image_url": "https://lynxkite.com/favicon.png"},
94
+ }
95
+ ],
96
+ }
97
+ return {"error": "Not found"}
98
+
99
+ async def post(self, request: fastapi.Request) -> dict:
100
+ if request.state.remaining_path == "chat/completions":
101
+ request = await request.json()
102
+ if request["stream"]:
103
+ from sse_starlette.sse import EventSourceResponse
104
+
105
+ return EventSourceResponse(self.stream_chat_api_response(request))
106
+ else:
107
+ return await self.get_chat_api_response(request)
108
+ return {"error": "Not found"}
109
+
110
+ async def stream_chat_api_response(self, request):
111
+ request = ChatCompletionPrompt(**request)
112
+ async for chunk in await self.chat_api.answer(request, stream=True):
113
+ chunk.choices[0].delta.content += f"({self.agent})"
114
+ yield chunk.model_dump_json()
115
+
116
+ async def get_chat_api_response(self, request):
117
+ request = ChatCompletionPrompt(**request)
118
+ response = await self.chat_api.answer(request, stream=False)
119
+ return response.model_dump()
examples/LynxScribe/ChatAPI/demo.sh ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash -xue
2
+ # xh POST 'https://api.openai.com/v1/chat/completions' \
3
+ # Authorization:"Bearer $OPENAI_API_KEY" \
4
+ # model=gpt-4o-mini \
5
+ # stream:=false \
6
+ # messages:='[{"role": "user", "content": "what does the fox say"}]'
7
+
8
+ xh 'http://localhost:8000/api/service/lynxkite_graph_analytics/LynxScribe%20MCP/Demo.lynxkite.json/Chat%20frontend%201/models'
9
+
10
+ xh POST 'http://localhost:8000/api/service/lynxkite_graph_analytics/LynxScribe%20MCP/Demo.lynxkite.json/Chat%20frontend%201/chat/completions' \
11
+ model=LynxScribe \
12
+ stream:=false \
13
+ messages:='[{"role": "user", "content": "what does the fox say"}]'
examples/LynxScribe/ChatAPI/requirements.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ ../../lynxscribe
examples/LynxScribe/MCP/Demo.lynxkite.json ADDED
@@ -0,0 +1,1050 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "edges": [
3
+ {
4
+ "id": "Database 1 output MCP: Query database with SQL 2 db",
5
+ "source": "Database 1",
6
+ "sourceHandle": "output",
7
+ "target": "MCP: Query database with SQL 2",
8
+ "targetHandle": "db"
9
+ },
10
+ {
11
+ "id": "Ladder graph 1 output PageRank 1 G",
12
+ "source": "Ladder graph 1",
13
+ "sourceHandle": "output",
14
+ "target": "PageRank 1",
15
+ "targetHandle": "G"
16
+ },
17
+ {
18
+ "id": "PageRank 1 output Database 1 data_pipeline",
19
+ "source": "PageRank 1",
20
+ "sourceHandle": "output",
21
+ "target": "Database 1",
22
+ "targetHandle": "data_pipeline"
23
+ },
24
+ {
25
+ "id": "Karate club graph 1 output Common neighbor centrality 1 G",
26
+ "source": "Karate club graph 1",
27
+ "sourceHandle": "output",
28
+ "target": "Common neighbor centrality 1",
29
+ "targetHandle": "G"
30
+ },
31
+ {
32
+ "id": "Common neighbor centrality 1 output Database 1 data_pipeline",
33
+ "source": "Common neighbor centrality 1",
34
+ "sourceHandle": "output",
35
+ "target": "Database 1",
36
+ "targetHandle": "data_pipeline"
37
+ },
38
+ {
39
+ "id": "Import file 1 output SQL 1 bundle",
40
+ "source": "Import file 1",
41
+ "sourceHandle": "output",
42
+ "target": "SQL 1",
43
+ "targetHandle": "bundle"
44
+ },
45
+ {
46
+ "id": "SQL 1 output SQL 2 bundle",
47
+ "source": "SQL 1",
48
+ "sourceHandle": "output",
49
+ "target": "SQL 2",
50
+ "targetHandle": "bundle"
51
+ },
52
+ {
53
+ "id": "SQL 2 output Database 1 data_pipeline",
54
+ "source": "SQL 2",
55
+ "sourceHandle": "output",
56
+ "target": "Database 1",
57
+ "targetHandle": "data_pipeline"
58
+ },
59
+ {
60
+ "id": "Agent 2 output Chat frontend 1 agent",
61
+ "source": "Agent 2",
62
+ "sourceHandle": "output",
63
+ "target": "Chat frontend 1",
64
+ "targetHandle": "agent"
65
+ },
66
+ {
67
+ "id": "MCP: Calculator 1 output Agent 2 tools",
68
+ "source": "MCP: Calculator 1",
69
+ "sourceHandle": "output",
70
+ "target": "Agent 2",
71
+ "targetHandle": "tools"
72
+ },
73
+ {
74
+ "id": "MCP: Query database with SQL 2 output Agent 2 tools",
75
+ "source": "MCP: Query database with SQL 2",
76
+ "sourceHandle": "output",
77
+ "target": "Agent 2",
78
+ "targetHandle": "tools"
79
+ },
80
+ {
81
+ "id": "MCP: Financial data 1 output Agent 2 tools",
82
+ "source": "MCP: Financial data 1",
83
+ "sourceHandle": "output",
84
+ "target": "Agent 2",
85
+ "targetHandle": "tools"
86
+ },
87
+ {
88
+ "id": "MCP: Search web 1 output Agent 2 tools",
89
+ "source": "MCP: Search web 1",
90
+ "sourceHandle": "output",
91
+ "target": "Agent 2",
92
+ "targetHandle": "tools"
93
+ }
94
+ ],
95
+ "env": "LynxKite Graph Analytics",
96
+ "nodes": [
97
+ {
98
+ "data": {
99
+ "collapsed": true,
100
+ "display": null,
101
+ "error": null,
102
+ "input_metadata": [
103
+ {}
104
+ ],
105
+ "meta": {
106
+ "categories": [
107
+ "Data Science"
108
+ ],
109
+ "color": "orange",
110
+ "doc": null,
111
+ "id": "Data Science > Database",
112
+ "inputs": [
113
+ {
114
+ "name": "data_pipeline",
115
+ "position": "left",
116
+ "type": {
117
+ "type": "list[lynxkite_graph_analytics.core.Bundle]"
118
+ }
119
+ }
120
+ ],
121
+ "name": "Database",
122
+ "outputs": [
123
+ {
124
+ "name": "output",
125
+ "position": "top",
126
+ "type": {
127
+ "type": "None"
128
+ }
129
+ }
130
+ ],
131
+ "params": [],
132
+ "type": "basic"
133
+ },
134
+ "op_id": "Data Science > Database",
135
+ "params": {},
136
+ "status": "done",
137
+ "title": "Database"
138
+ },
139
+ "dragHandle": ".drag-handle",
140
+ "height": 200.0,
141
+ "id": "Database 1",
142
+ "position": {
143
+ "x": -175.8708861292469,
144
+ "y": 465.47762360072204
145
+ },
146
+ "type": "basic",
147
+ "width": 200.0
148
+ },
149
+ {
150
+ "data": {
151
+ "__execution_delay": 0.0,
152
+ "collapsed": true,
153
+ "display": null,
154
+ "error": null,
155
+ "input_metadata": [],
156
+ "meta": {
157
+ "categories": [
158
+ "NetworkX",
159
+ "Generators",
160
+ "Classic"
161
+ ],
162
+ "color": "orange",
163
+ "doc": null,
164
+ "id": "NetworkX > Generators > Classic > Ladder graph",
165
+ "inputs": [],
166
+ "name": "Ladder graph",
167
+ "outputs": [
168
+ {
169
+ "name": "output",
170
+ "position": "right",
171
+ "type": {
172
+ "type": "<class 'networkx.classes.graph.Graph'>"
173
+ }
174
+ }
175
+ ],
176
+ "params": [
177
+ {
178
+ "default": null,
179
+ "name": "n",
180
+ "type": {
181
+ "type": "<class 'int'>"
182
+ }
183
+ }
184
+ ],
185
+ "type": "basic"
186
+ },
187
+ "op_id": "NetworkX > Generators > Classic > Ladder graph",
188
+ "params": {
189
+ "n": "11"
190
+ },
191
+ "status": "done",
192
+ "title": "Ladder graph"
193
+ },
194
+ "dragHandle": ".drag-handle",
195
+ "height": 200.0,
196
+ "id": "Ladder graph 1",
197
+ "position": {
198
+ "x": -1297.4471345569843,
199
+ "y": 364.99969784589774
200
+ },
201
+ "type": "basic",
202
+ "width": 200.0
203
+ },
204
+ {
205
+ "data": {
206
+ "collapsed": true,
207
+ "display": null,
208
+ "error": null,
209
+ "input_metadata": [
210
+ {}
211
+ ],
212
+ "meta": {
213
+ "categories": [
214
+ "LynxScribe"
215
+ ],
216
+ "color": "green",
217
+ "doc": null,
218
+ "id": "LynxScribe > MCP: Query database with SQL",
219
+ "inputs": [
220
+ {
221
+ "name": "db",
222
+ "position": "bottom",
223
+ "type": {
224
+ "type": "<class 'str'>"
225
+ }
226
+ }
227
+ ],
228
+ "name": "MCP: Query database with SQL",
229
+ "outputs": [
230
+ {
231
+ "name": "output",
232
+ "position": "top",
233
+ "type": {
234
+ "type": "None"
235
+ }
236
+ }
237
+ ],
238
+ "params": [],
239
+ "type": "basic"
240
+ },
241
+ "op_id": "LynxScribe > MCP: Query database with SQL",
242
+ "params": {},
243
+ "status": "done",
244
+ "title": "MCP: Query database with SQL"
245
+ },
246
+ "dragHandle": ".drag-handle",
247
+ "height": 152.0,
248
+ "id": "MCP: Query database with SQL 2",
249
+ "position": {
250
+ "x": -248.451978071668,
251
+ "y": 231.5655840074671
252
+ },
253
+ "type": "basic",
254
+ "width": 334.0
255
+ },
256
+ {
257
+ "data": {
258
+ "collapsed": true,
259
+ "display": null,
260
+ "error": null,
261
+ "input_metadata": [],
262
+ "meta": {
263
+ "categories": [
264
+ "LynxScribe"
265
+ ],
266
+ "color": "green",
267
+ "doc": null,
268
+ "id": "LynxScribe > MCP: Calculator",
269
+ "inputs": [],
270
+ "name": "MCP: Calculator",
271
+ "outputs": [
272
+ {
273
+ "name": "output",
274
+ "position": "top",
275
+ "type": {
276
+ "type": "None"
277
+ }
278
+ }
279
+ ],
280
+ "params": [],
281
+ "type": "basic"
282
+ },
283
+ "op_id": "LynxScribe > MCP: Calculator",
284
+ "params": {},
285
+ "status": "done",
286
+ "title": "MCP: Calculator"
287
+ },
288
+ "dragHandle": ".drag-handle",
289
+ "height": 200.0,
290
+ "id": "MCP: Calculator 1",
291
+ "position": {
292
+ "x": -527.6679408294542,
293
+ "y": 240.503939070944
294
+ },
295
+ "type": "basic",
296
+ "width": 200.0
297
+ },
298
+ {
299
+ "data": {
300
+ "collapsed": false,
301
+ "display": {
302
+ "dataframes": {
303
+ "service": {
304
+ "columns": [
305
+ "markdown"
306
+ ],
307
+ "data": [
308
+ [
309
+ "[Go to frontend](http://localhost:8501/?service=%2Fapi%2Fservice%2Flynxkite_graph_analytics%2FLynxScribe%2FMCP%2FDemo.lynxkite.json%2FChat+frontend+1/chat/completions)"
310
+ ]
311
+ ]
312
+ }
313
+ }
314
+ },
315
+ "error": null,
316
+ "input_metadata": [
317
+ {}
318
+ ],
319
+ "meta": {
320
+ "categories": [
321
+ "LynxScribe"
322
+ ],
323
+ "color": "gray",
324
+ "doc": null,
325
+ "id": "LynxScribe > Chat frontend",
326
+ "inputs": [
327
+ {
328
+ "name": "agent",
329
+ "position": "bottom",
330
+ "type": {
331
+ "type": "<class 'dict'>"
332
+ }
333
+ }
334
+ ],
335
+ "name": "Chat frontend",
336
+ "outputs": [],
337
+ "params": [],
338
+ "type": "service"
339
+ },
340
+ "op_id": "LynxScribe > Chat frontend",
341
+ "params": {},
342
+ "status": "done",
343
+ "title": "Chat frontend"
344
+ },
345
+ "dragHandle": ".drag-handle",
346
+ "height": 117.0,
347
+ "id": "Chat frontend 1",
348
+ "position": {
349
+ "x": -1.8364143940130049,
350
+ "y": -692.5252605263688
351
+ },
352
+ "type": "service",
353
+ "width": 169.0
354
+ },
355
+ {
356
+ "data": {
357
+ "collapsed": true,
358
+ "display": null,
359
+ "error": null,
360
+ "input_metadata": [
361
+ {}
362
+ ],
363
+ "meta": {
364
+ "categories": [
365
+ "NetworkX",
366
+ "Algorithms",
367
+ "Link analysis",
368
+ "PageRank alg"
369
+ ],
370
+ "color": "orange",
371
+ "doc": null,
372
+ "id": "NetworkX > Algorithms > Link analysis > PageRank alg > PageRank",
373
+ "inputs": [
374
+ {
375
+ "name": "G",
376
+ "position": "left",
377
+ "type": {
378
+ "type": "<class 'networkx.classes.graph.Graph'>"
379
+ }
380
+ }
381
+ ],
382
+ "name": "PageRank",
383
+ "outputs": [
384
+ {
385
+ "name": "output",
386
+ "position": "right",
387
+ "type": {
388
+ "type": "<class 'networkx.classes.graph.Graph'>"
389
+ }
390
+ }
391
+ ],
392
+ "params": [
393
+ {
394
+ "default": "0.85",
395
+ "name": "alpha",
396
+ "type": {
397
+ "type": "float | None"
398
+ }
399
+ },
400
+ {
401
+ "default": "100",
402
+ "name": "max_iter",
403
+ "type": {
404
+ "type": "int | None"
405
+ }
406
+ },
407
+ {
408
+ "default": "1e-06",
409
+ "name": "tol",
410
+ "type": {
411
+ "type": "float | None"
412
+ }
413
+ },
414
+ {
415
+ "default": "weight",
416
+ "name": "weight",
417
+ "type": {
418
+ "type": "str | None"
419
+ }
420
+ }
421
+ ],
422
+ "type": "basic"
423
+ },
424
+ "op_id": "NetworkX > Algorithms > Link analysis > PageRank alg > PageRank",
425
+ "params": {
426
+ "alpha": "0.85",
427
+ "max_iter": "100",
428
+ "tol": "1e-06",
429
+ "weight": "weight"
430
+ },
431
+ "status": "done",
432
+ "title": "PageRank"
433
+ },
434
+ "dragHandle": ".drag-handle",
435
+ "height": 200.0,
436
+ "id": "PageRank 1",
437
+ "position": {
438
+ "x": -878.5796659405156,
439
+ "y": 369.96445264090244
440
+ },
441
+ "type": "basic",
442
+ "width": 200.0
443
+ },
444
+ {
445
+ "data": {
446
+ "collapsed": true,
447
+ "display": null,
448
+ "error": null,
449
+ "input_metadata": [],
450
+ "meta": {
451
+ "categories": [
452
+ "NetworkX",
453
+ "Generators",
454
+ "Social"
455
+ ],
456
+ "color": "orange",
457
+ "doc": null,
458
+ "id": "NetworkX > Generators > Social > Karate club graph",
459
+ "inputs": [],
460
+ "name": "Karate club graph",
461
+ "outputs": [
462
+ {
463
+ "name": "output",
464
+ "position": "right",
465
+ "type": {
466
+ "type": "<class 'networkx.classes.graph.Graph'>"
467
+ }
468
+ }
469
+ ],
470
+ "params": [],
471
+ "type": "basic"
472
+ },
473
+ "op_id": "NetworkX > Generators > Social > Karate club graph",
474
+ "params": {},
475
+ "status": "done",
476
+ "title": "Karate club graph"
477
+ },
478
+ "dragHandle": ".drag-handle",
479
+ "height": 200.0,
480
+ "id": "Karate club graph 1",
481
+ "position": {
482
+ "x": -1304.6391517192224,
483
+ "y": 585.0242219568652
484
+ },
485
+ "type": "basic",
486
+ "width": 200.0
487
+ },
488
+ {
489
+ "data": {
490
+ "collapsed": true,
491
+ "display": null,
492
+ "error": null,
493
+ "input_metadata": [
494
+ {}
495
+ ],
496
+ "meta": {
497
+ "categories": [
498
+ "NetworkX",
499
+ "Algorithms",
500
+ "Link prediction"
501
+ ],
502
+ "color": "orange",
503
+ "doc": null,
504
+ "id": "NetworkX > Algorithms > Link prediction > Common neighbor centrality",
505
+ "inputs": [
506
+ {
507
+ "name": "G",
508
+ "position": "left",
509
+ "type": {
510
+ "type": "<class 'networkx.classes.graph.Graph'>"
511
+ }
512
+ }
513
+ ],
514
+ "name": "Common neighbor centrality",
515
+ "outputs": [
516
+ {
517
+ "name": "output",
518
+ "position": "right",
519
+ "type": {
520
+ "type": "<class 'networkx.classes.graph.Graph'>"
521
+ }
522
+ }
523
+ ],
524
+ "params": [],
525
+ "type": "basic"
526
+ },
527
+ "op_id": "NetworkX > Algorithms > Link prediction > Common neighbor centrality",
528
+ "params": {},
529
+ "status": "done",
530
+ "title": "Common neighbor centrality"
531
+ },
532
+ "dragHandle": ".drag-handle",
533
+ "height": 130.0,
534
+ "id": "Common neighbor centrality 1",
535
+ "position": {
536
+ "x": -990.2453153930347,
537
+ "y": 587.3192401780905
538
+ },
539
+ "type": "basic",
540
+ "width": 341.0
541
+ },
542
+ {
543
+ "data": {
544
+ "__execution_delay": 0.0,
545
+ "collapsed": true,
546
+ "display": null,
547
+ "error": null,
548
+ "input_metadata": [],
549
+ "meta": {
550
+ "categories": [],
551
+ "color": "orange",
552
+ "doc": [
553
+ {
554
+ "kind": "text",
555
+ "value": "Read the contents of the a file into a `Bundle`."
556
+ },
557
+ {
558
+ "kind": "parameters",
559
+ "value": [
560
+ {
561
+ "annotation": "str",
562
+ "description": "Path to the file to import.",
563
+ "name": "file_path"
564
+ },
565
+ {
566
+ "annotation": "str",
567
+ "description": "Name to use for identifying the table in the bundle.",
568
+ "name": "table_name"
569
+ },
570
+ {
571
+ "annotation": "FileFormat",
572
+ "description": "Format of the file. Has to be one of the values in the `FileFormat` enum.",
573
+ "name": "file_format"
574
+ }
575
+ ]
576
+ },
577
+ {
578
+ "kind": "returns",
579
+ "value": [
580
+ {
581
+ "annotation": "<class 'lynxkite_graph_analytics.core.Bundle'>",
582
+ "description": "Bundle with a single table with the contents of the file.",
583
+ "name": "Bundle"
584
+ }
585
+ ]
586
+ }
587
+ ],
588
+ "id": "Import file",
589
+ "inputs": [],
590
+ "name": "Import file",
591
+ "outputs": [
592
+ {
593
+ "name": "output",
594
+ "position": "right",
595
+ "type": {
596
+ "type": "None"
597
+ }
598
+ }
599
+ ],
600
+ "params": [
601
+ {
602
+ "default": null,
603
+ "name": "file_path",
604
+ "type": {
605
+ "type": "<class 'str'>"
606
+ }
607
+ },
608
+ {
609
+ "default": null,
610
+ "name": "table_name",
611
+ "type": {
612
+ "type": "<class 'str'>"
613
+ }
614
+ },
615
+ {
616
+ "default": "csv",
617
+ "name": "file_format",
618
+ "type": {
619
+ "enum": [
620
+ "csv",
621
+ "parquet",
622
+ "json",
623
+ "excel"
624
+ ]
625
+ }
626
+ },
627
+ {
628
+ "default": "csv",
629
+ "groups": {
630
+ "csv": [
631
+ {
632
+ "default": "<from file>",
633
+ "name": "columns",
634
+ "type": {
635
+ "type": "<class 'str'>"
636
+ }
637
+ },
638
+ {
639
+ "default": "<auto>",
640
+ "name": "separator",
641
+ "type": {
642
+ "type": "<class 'str'>"
643
+ }
644
+ }
645
+ ],
646
+ "excel": [
647
+ {
648
+ "default": "Sheet1",
649
+ "name": "sheet_name",
650
+ "type": {
651
+ "type": "<class 'str'>"
652
+ }
653
+ }
654
+ ],
655
+ "json": [],
656
+ "parquet": []
657
+ },
658
+ "name": "file_format_group",
659
+ "selector": {
660
+ "default": "csv",
661
+ "name": "file_format",
662
+ "type": {
663
+ "enum": [
664
+ "csv",
665
+ "parquet",
666
+ "json",
667
+ "excel"
668
+ ]
669
+ }
670
+ },
671
+ "type": "group"
672
+ }
673
+ ],
674
+ "type": "basic"
675
+ },
676
+ "op_id": "Import file",
677
+ "params": {
678
+ "file_format": "csv",
679
+ "file_format_group": "csv",
680
+ "file_path": "uploads/molecules2.csv",
681
+ "table_name": "molecules"
682
+ },
683
+ "status": "done",
684
+ "title": "Import file"
685
+ },
686
+ "dragHandle": ".drag-handle",
687
+ "height": 393.0,
688
+ "id": "Import file 1",
689
+ "position": {
690
+ "x": -1411.4491034838866,
691
+ "y": 772.1675932822765
692
+ },
693
+ "type": "basic",
694
+ "width": 369.0
695
+ },
696
+ {
697
+ "data": {
698
+ "__execution_delay": 0.0,
699
+ "collapsed": true,
700
+ "display": null,
701
+ "error": null,
702
+ "input_metadata": [
703
+ {
704
+ "dataframes": {
705
+ "molecules": {
706
+ "columns": [
707
+ "name",
708
+ "smiles"
709
+ ],
710
+ "key": "molecules"
711
+ }
712
+ },
713
+ "other": {},
714
+ "relations": []
715
+ }
716
+ ],
717
+ "meta": {
718
+ "categories": [],
719
+ "color": "orange",
720
+ "doc": [
721
+ {
722
+ "kind": "text",
723
+ "value": "Run a SQL query on the DataFrames in the bundle. Save the results as a new DataFrame."
724
+ }
725
+ ],
726
+ "id": "SQL",
727
+ "inputs": [
728
+ {
729
+ "name": "bundle",
730
+ "position": "left",
731
+ "type": {
732
+ "type": "<class 'lynxkite_graph_analytics.core.Bundle'>"
733
+ }
734
+ }
735
+ ],
736
+ "name": "SQL",
737
+ "outputs": [
738
+ {
739
+ "name": "output",
740
+ "position": "right",
741
+ "type": {
742
+ "type": "None"
743
+ }
744
+ }
745
+ ],
746
+ "params": [
747
+ {
748
+ "default": null,
749
+ "name": "query",
750
+ "type": {
751
+ "format": "textarea"
752
+ }
753
+ },
754
+ {
755
+ "default": "result",
756
+ "name": "save_as",
757
+ "type": {
758
+ "type": "<class 'str'>"
759
+ }
760
+ }
761
+ ],
762
+ "type": "basic"
763
+ },
764
+ "op_id": "SQL",
765
+ "params": {
766
+ "query": "select *",
767
+ "save_as": "result"
768
+ },
769
+ "status": "done",
770
+ "title": "SQL"
771
+ },
772
+ "dragHandle": ".drag-handle",
773
+ "height": 200.0,
774
+ "id": "SQL 1",
775
+ "position": {
776
+ "x": -931.2061769202694,
777
+ "y": 766.0054007337461
778
+ },
779
+ "type": "basic",
780
+ "width": 200.0
781
+ },
782
+ {
783
+ "data": {
784
+ "__execution_delay": 0.0,
785
+ "collapsed": true,
786
+ "display": null,
787
+ "error": null,
788
+ "input_metadata": [
789
+ {
790
+ "dataframes": {
791
+ "molecules": {
792
+ "columns": [
793
+ "name",
794
+ "smiles"
795
+ ],
796
+ "key": "molecules"
797
+ },
798
+ "result": {
799
+ "columns": [],
800
+ "key": "result"
801
+ }
802
+ },
803
+ "other": {},
804
+ "relations": []
805
+ }
806
+ ],
807
+ "meta": {
808
+ "categories": [],
809
+ "color": "orange",
810
+ "doc": [
811
+ {
812
+ "kind": "text",
813
+ "value": "Run a SQL query on the DataFrames in the bundle. Save the results as a new DataFrame."
814
+ }
815
+ ],
816
+ "id": "SQL",
817
+ "inputs": [
818
+ {
819
+ "name": "bundle",
820
+ "position": "left",
821
+ "type": {
822
+ "type": "<class 'lynxkite_graph_analytics.core.Bundle'>"
823
+ }
824
+ }
825
+ ],
826
+ "name": "SQL",
827
+ "outputs": [
828
+ {
829
+ "name": "output",
830
+ "position": "right",
831
+ "type": {
832
+ "type": "None"
833
+ }
834
+ }
835
+ ],
836
+ "params": [
837
+ {
838
+ "default": null,
839
+ "name": "query",
840
+ "type": {
841
+ "format": "textarea"
842
+ }
843
+ },
844
+ {
845
+ "default": "result",
846
+ "name": "save_as",
847
+ "type": {
848
+ "type": "<class 'str'>"
849
+ }
850
+ }
851
+ ],
852
+ "type": "basic"
853
+ },
854
+ "op_id": "SQL",
855
+ "params": {
856
+ "query": "select *",
857
+ "save_as": "result"
858
+ },
859
+ "status": "done",
860
+ "title": "SQL"
861
+ },
862
+ "dragHandle": ".drag-handle",
863
+ "height": 200.0,
864
+ "id": "SQL 2",
865
+ "position": {
866
+ "x": -633.7783633982368,
867
+ "y": 767.4541281209835
868
+ },
869
+ "type": "basic",
870
+ "width": 200.0
871
+ },
872
+ {
873
+ "data": {
874
+ "collapsed": true,
875
+ "display": null,
876
+ "error": null,
877
+ "input_metadata": [],
878
+ "meta": {
879
+ "categories": [
880
+ "LynxScribe"
881
+ ],
882
+ "color": "green",
883
+ "doc": null,
884
+ "id": "LynxScribe > MCP: Financial data",
885
+ "inputs": [],
886
+ "name": "MCP: Financial data",
887
+ "outputs": [
888
+ {
889
+ "name": "output",
890
+ "position": "top",
891
+ "type": {
892
+ "type": "None"
893
+ }
894
+ }
895
+ ],
896
+ "params": [],
897
+ "type": "basic"
898
+ },
899
+ "op_id": "LynxScribe > MCP: Financial data",
900
+ "params": {},
901
+ "status": "done",
902
+ "title": "MCP: Financial data"
903
+ },
904
+ "dragHandle": ".drag-handle",
905
+ "height": 175.0,
906
+ "id": "MCP: Financial data 1",
907
+ "position": {
908
+ "x": 158.4345441423415,
909
+ "y": 229.50555825204884
910
+ },
911
+ "type": "basic",
912
+ "width": 242.0
913
+ },
914
+ {
915
+ "data": {
916
+ "__execution_delay": 0.0,
917
+ "display": null,
918
+ "error": null,
919
+ "input_metadata": [],
920
+ "meta": {
921
+ "categories": [
922
+ "LynxScribe"
923
+ ],
924
+ "color": "green",
925
+ "doc": null,
926
+ "id": "LynxScribe > MCP: Search web",
927
+ "inputs": [],
928
+ "name": "MCP: Search web",
929
+ "outputs": [
930
+ {
931
+ "name": "output",
932
+ "position": "top",
933
+ "type": {
934
+ "type": "None"
935
+ }
936
+ }
937
+ ],
938
+ "params": [
939
+ {
940
+ "default": "Google",
941
+ "name": "engine",
942
+ "type": {
943
+ "enum": [
944
+ "Google",
945
+ "Bing",
946
+ "DuckDuckGo"
947
+ ]
948
+ }
949
+ }
950
+ ],
951
+ "type": "basic"
952
+ },
953
+ "op_id": "LynxScribe > MCP: Search web",
954
+ "params": {
955
+ "engine": "DuckDuckGo"
956
+ },
957
+ "status": "done",
958
+ "title": "MCP: Search web"
959
+ },
960
+ "dragHandle": ".drag-handle",
961
+ "height": 200.0,
962
+ "id": "MCP: Search web 1",
963
+ "position": {
964
+ "x": 540.4008718602887,
965
+ "y": 249.69009586836748
966
+ },
967
+ "type": "basic",
968
+ "width": 200.0
969
+ },
970
+ {
971
+ "data": {
972
+ "__execution_delay": 0.0,
973
+ "display": null,
974
+ "error": null,
975
+ "input_metadata": [
976
+ {}
977
+ ],
978
+ "meta": {
979
+ "categories": [
980
+ "LynxScribe"
981
+ ],
982
+ "color": "blue",
983
+ "doc": null,
984
+ "id": "LynxScribe > Agent",
985
+ "inputs": [
986
+ {
987
+ "name": "tools",
988
+ "position": "bottom",
989
+ "type": {
990
+ "type": "list[dict]"
991
+ }
992
+ }
993
+ ],
994
+ "name": "Agent",
995
+ "outputs": [
996
+ {
997
+ "name": "output",
998
+ "position": "top",
999
+ "type": {
1000
+ "type": "None"
1001
+ }
1002
+ }
1003
+ ],
1004
+ "params": [
1005
+ {
1006
+ "default": "",
1007
+ "name": "name",
1008
+ "type": {
1009
+ "type": "<class 'str'>"
1010
+ }
1011
+ },
1012
+ {
1013
+ "default": "This agent helps with various tasks.",
1014
+ "name": "description",
1015
+ "type": {
1016
+ "format": "textarea"
1017
+ }
1018
+ },
1019
+ {
1020
+ "default": "You are a helpful assistant.",
1021
+ "name": "system_prompt",
1022
+ "type": {
1023
+ "format": "textarea"
1024
+ }
1025
+ }
1026
+ ],
1027
+ "type": "basic"
1028
+ },
1029
+ "op_id": "LynxScribe > Agent",
1030
+ "params": {
1031
+ "description": "",
1032
+ "name": "",
1033
+ "system_prompt": "Using the tools at your disposal answer all questions in an extremely cheerful tone.\nFor queries about movies use the database, not web search.\nFormat the answer as Markdown. Use emojis abundantly."
1034
+ },
1035
+ "status": "done",
1036
+ "title": "Agent"
1037
+ },
1038
+ "dragHandle": ".drag-handle",
1039
+ "height": 438.0,
1040
+ "id": "Agent 2",
1041
+ "position": {
1042
+ "x": -219.84159684352335,
1043
+ "y": -476.0077657450069
1044
+ },
1045
+ "type": "basic",
1046
+ "width": 602.0
1047
+ }
1048
+ ],
1049
+ "paused": false
1050
+ }
examples/LynxScribe/MCP/Multi-agent.lynxkite.json ADDED
@@ -0,0 +1,599 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "edges": [
3
+ {
4
+ "id": "Database 1 output MCP: Query database with SQL 2 db",
5
+ "source": "Database 1",
6
+ "sourceHandle": "output",
7
+ "target": "MCP: Query database with SQL 2",
8
+ "targetHandle": "db"
9
+ },
10
+ {
11
+ "id": "Agent 2 output Chat frontend 1 agent",
12
+ "source": "Agent 2",
13
+ "sourceHandle": "output",
14
+ "target": "Chat frontend 1",
15
+ "targetHandle": "agent"
16
+ },
17
+ {
18
+ "id": "MCP: Calculator 1 output Agent 4 tools",
19
+ "source": "MCP: Calculator 1",
20
+ "sourceHandle": "output",
21
+ "target": "Agent 4",
22
+ "targetHandle": "tools"
23
+ },
24
+ {
25
+ "id": "MCP: Query database with SQL 2 output Agent 3 tools",
26
+ "source": "MCP: Query database with SQL 2",
27
+ "sourceHandle": "output",
28
+ "target": "Agent 3",
29
+ "targetHandle": "tools"
30
+ },
31
+ {
32
+ "id": "MCP: Financial data 1 output Agent 3 tools",
33
+ "source": "MCP: Financial data 1",
34
+ "sourceHandle": "output",
35
+ "target": "Agent 3",
36
+ "targetHandle": "tools"
37
+ },
38
+ {
39
+ "id": "Agent 3 output Agent 2 tools",
40
+ "source": "Agent 3",
41
+ "sourceHandle": "output",
42
+ "target": "Agent 2",
43
+ "targetHandle": "tools"
44
+ },
45
+ {
46
+ "id": "Agent 4 output Agent 2 tools",
47
+ "source": "Agent 4",
48
+ "sourceHandle": "output",
49
+ "target": "Agent 2",
50
+ "targetHandle": "tools"
51
+ },
52
+ {
53
+ "id": "MCP: Search web 1 output Agent 2 tools",
54
+ "source": "MCP: Search web 1",
55
+ "sourceHandle": "output",
56
+ "target": "Agent 2",
57
+ "targetHandle": "tools"
58
+ }
59
+ ],
60
+ "env": "LynxKite Graph Analytics",
61
+ "nodes": [
62
+ {
63
+ "data": {
64
+ "collapsed": true,
65
+ "display": null,
66
+ "error": null,
67
+ "input_metadata": [
68
+ {}
69
+ ],
70
+ "meta": {
71
+ "categories": [
72
+ "Data Science"
73
+ ],
74
+ "color": "orange",
75
+ "doc": null,
76
+ "id": "Data Science > Database",
77
+ "inputs": [
78
+ {
79
+ "name": "data_pipeline",
80
+ "position": "left",
81
+ "type": {
82
+ "type": "list[lynxkite_graph_analytics.core.Bundle]"
83
+ }
84
+ }
85
+ ],
86
+ "name": "Database",
87
+ "outputs": [
88
+ {
89
+ "name": "output",
90
+ "position": "top",
91
+ "type": {
92
+ "type": "None"
93
+ }
94
+ }
95
+ ],
96
+ "params": [],
97
+ "type": "basic"
98
+ },
99
+ "op_id": "Data Science > Database",
100
+ "params": {},
101
+ "status": "done",
102
+ "title": "Database"
103
+ },
104
+ "dragHandle": ".drag-handle",
105
+ "height": 200.0,
106
+ "id": "Database 1",
107
+ "position": {
108
+ "x": -175.8708861292469,
109
+ "y": 465.47762360072204
110
+ },
111
+ "type": "basic",
112
+ "width": 200.0
113
+ },
114
+ {
115
+ "data": {
116
+ "collapsed": true,
117
+ "display": null,
118
+ "error": null,
119
+ "input_metadata": [
120
+ {}
121
+ ],
122
+ "meta": {
123
+ "categories": [
124
+ "LynxScribe"
125
+ ],
126
+ "color": "green",
127
+ "doc": null,
128
+ "id": "LynxScribe > MCP: Query database with SQL",
129
+ "inputs": [
130
+ {
131
+ "name": "db",
132
+ "position": "bottom",
133
+ "type": {
134
+ "type": "<class 'str'>"
135
+ }
136
+ }
137
+ ],
138
+ "name": "MCP: Query database with SQL",
139
+ "outputs": [
140
+ {
141
+ "name": "output",
142
+ "position": "top",
143
+ "type": {
144
+ "type": "None"
145
+ }
146
+ }
147
+ ],
148
+ "params": [],
149
+ "type": "basic"
150
+ },
151
+ "op_id": "LynxScribe > MCP: Query database with SQL",
152
+ "params": {},
153
+ "status": "done",
154
+ "title": "MCP: Query database with SQL"
155
+ },
156
+ "dragHandle": ".drag-handle",
157
+ "height": 152.0,
158
+ "id": "MCP: Query database with SQL 2",
159
+ "position": {
160
+ "x": -248.451978071668,
161
+ "y": 231.5655840074671
162
+ },
163
+ "type": "basic",
164
+ "width": 334.0
165
+ },
166
+ {
167
+ "data": {
168
+ "collapsed": true,
169
+ "display": null,
170
+ "error": null,
171
+ "input_metadata": [],
172
+ "meta": {
173
+ "categories": [
174
+ "LynxScribe"
175
+ ],
176
+ "color": "green",
177
+ "doc": null,
178
+ "id": "LynxScribe > MCP: Calculator",
179
+ "inputs": [],
180
+ "name": "MCP: Calculator",
181
+ "outputs": [
182
+ {
183
+ "name": "output",
184
+ "position": "top",
185
+ "type": {
186
+ "type": "None"
187
+ }
188
+ }
189
+ ],
190
+ "params": [],
191
+ "type": "basic"
192
+ },
193
+ "op_id": "LynxScribe > MCP: Calculator",
194
+ "params": {},
195
+ "status": "done",
196
+ "title": "MCP: Calculator"
197
+ },
198
+ "dragHandle": ".drag-handle",
199
+ "height": 200.0,
200
+ "id": "MCP: Calculator 1",
201
+ "position": {
202
+ "x": 703.3290222575753,
203
+ "y": 200.27528014653126
204
+ },
205
+ "type": "basic",
206
+ "width": 200.0
207
+ },
208
+ {
209
+ "data": {
210
+ "collapsed": true,
211
+ "display": {
212
+ "dataframes": {
213
+ "service": {
214
+ "columns": [
215
+ "url"
216
+ ],
217
+ "data": [
218
+ [
219
+ "/api/service/lynxkite_graph_analytics/LynxScribe/MCP/Multi-agent.lynxkite.json/Chat frontend 1"
220
+ ]
221
+ ]
222
+ }
223
+ }
224
+ },
225
+ "error": null,
226
+ "input_metadata": [
227
+ {}
228
+ ],
229
+ "meta": {
230
+ "categories": [
231
+ "LynxScribe"
232
+ ],
233
+ "color": "gray",
234
+ "doc": null,
235
+ "id": "LynxScribe > Chat frontend",
236
+ "inputs": [
237
+ {
238
+ "name": "agent",
239
+ "position": "bottom",
240
+ "type": {
241
+ "type": "<class 'dict'>"
242
+ }
243
+ }
244
+ ],
245
+ "name": "Chat frontend",
246
+ "outputs": [],
247
+ "params": [],
248
+ "type": "service"
249
+ },
250
+ "op_id": "LynxScribe > Chat frontend",
251
+ "params": {},
252
+ "status": "done",
253
+ "title": "Chat frontend"
254
+ },
255
+ "dragHandle": ".drag-handle",
256
+ "height": 362.0,
257
+ "id": "Chat frontend 1",
258
+ "position": {
259
+ "x": -146.7467273061735,
260
+ "y": -1261.9614951572912
261
+ },
262
+ "type": "service",
263
+ "width": 428.0
264
+ },
265
+ {
266
+ "data": {
267
+ "collapsed": true,
268
+ "display": null,
269
+ "error": null,
270
+ "input_metadata": [],
271
+ "meta": {
272
+ "categories": [
273
+ "LynxScribe"
274
+ ],
275
+ "color": "green",
276
+ "doc": null,
277
+ "id": "LynxScribe > MCP: Financial data",
278
+ "inputs": [],
279
+ "name": "MCP: Financial data",
280
+ "outputs": [
281
+ {
282
+ "name": "output",
283
+ "position": "top",
284
+ "type": {
285
+ "type": "None"
286
+ }
287
+ }
288
+ ],
289
+ "params": [],
290
+ "type": "basic"
291
+ },
292
+ "op_id": "LynxScribe > MCP: Financial data",
293
+ "params": {},
294
+ "status": "done",
295
+ "title": "MCP: Financial data"
296
+ },
297
+ "dragHandle": ".drag-handle",
298
+ "height": 175.0,
299
+ "id": "MCP: Financial data 1",
300
+ "position": {
301
+ "x": 158.4345441423415,
302
+ "y": 229.50555825204884
303
+ },
304
+ "type": "basic",
305
+ "width": 242.0
306
+ },
307
+ {
308
+ "data": {
309
+ "__execution_delay": 0.0,
310
+ "display": null,
311
+ "error": null,
312
+ "input_metadata": [],
313
+ "meta": {
314
+ "categories": [
315
+ "LynxScribe"
316
+ ],
317
+ "color": "green",
318
+ "doc": null,
319
+ "id": "LynxScribe > MCP: Search web",
320
+ "inputs": [],
321
+ "name": "MCP: Search web",
322
+ "outputs": [
323
+ {
324
+ "name": "output",
325
+ "position": "top",
326
+ "type": {
327
+ "type": "None"
328
+ }
329
+ }
330
+ ],
331
+ "params": [
332
+ {
333
+ "default": "Google",
334
+ "name": "engine",
335
+ "type": {
336
+ "enum": [
337
+ "Google",
338
+ "Bing",
339
+ "DuckDuckGo"
340
+ ]
341
+ }
342
+ }
343
+ ],
344
+ "type": "basic"
345
+ },
346
+ "op_id": "LynxScribe > MCP: Search web",
347
+ "params": {
348
+ "engine": "DuckDuckGo"
349
+ },
350
+ "status": "done",
351
+ "title": "MCP: Search web"
352
+ },
353
+ "dragHandle": ".drag-handle",
354
+ "height": 200.0,
355
+ "id": "MCP: Search web 1",
356
+ "position": {
357
+ "x": -631.594058137602,
358
+ "y": -415.42373168192296
359
+ },
360
+ "type": "basic",
361
+ "width": 200.0
362
+ },
363
+ {
364
+ "data": {
365
+ "__execution_delay": 0.0,
366
+ "display": null,
367
+ "error": null,
368
+ "input_metadata": [
369
+ {}
370
+ ],
371
+ "meta": {
372
+ "categories": [
373
+ "LynxScribe"
374
+ ],
375
+ "color": "blue",
376
+ "doc": null,
377
+ "id": "LynxScribe > Agent",
378
+ "inputs": [
379
+ {
380
+ "name": "tools",
381
+ "position": "bottom",
382
+ "type": {
383
+ "type": "list[dict]"
384
+ }
385
+ }
386
+ ],
387
+ "name": "Agent",
388
+ "outputs": [
389
+ {
390
+ "name": "output",
391
+ "position": "top",
392
+ "type": {
393
+ "type": "None"
394
+ }
395
+ }
396
+ ],
397
+ "params": [
398
+ {
399
+ "default": "",
400
+ "name": "name",
401
+ "type": {
402
+ "type": "<class 'str'>"
403
+ }
404
+ },
405
+ {
406
+ "default": "This agent helps with various tasks.",
407
+ "name": "description",
408
+ "type": {
409
+ "format": "textarea"
410
+ }
411
+ },
412
+ {
413
+ "default": "You are a helpful assistant.",
414
+ "name": "system_prompt",
415
+ "type": {
416
+ "format": "textarea"
417
+ }
418
+ }
419
+ ],
420
+ "type": "basic"
421
+ },
422
+ "op_id": "LynxScribe > Agent",
423
+ "params": {
424
+ "description": "",
425
+ "name": "Main conversation",
426
+ "system_prompt": "Use the agents and tools at your disposal to help the user.\nFormat the answer as Markdown. Make sure no LaTeX fragments remain."
427
+ },
428
+ "status": "done",
429
+ "title": "Agent"
430
+ },
431
+ "dragHandle": ".drag-handle",
432
+ "height": 354.0,
433
+ "id": "Agent 2",
434
+ "position": {
435
+ "x": -207.35812276980303,
436
+ "y": -1031.390517483489
437
+ },
438
+ "type": "basic",
439
+ "width": 552.0
440
+ },
441
+ {
442
+ "data": {
443
+ "__execution_delay": 0.0,
444
+ "display": null,
445
+ "error": null,
446
+ "input_metadata": [
447
+ {}
448
+ ],
449
+ "meta": {
450
+ "categories": [
451
+ "LynxScribe"
452
+ ],
453
+ "color": "blue",
454
+ "doc": null,
455
+ "id": "LynxScribe > Agent",
456
+ "inputs": [
457
+ {
458
+ "name": "tools",
459
+ "position": "bottom",
460
+ "type": {
461
+ "type": "list[dict]"
462
+ }
463
+ }
464
+ ],
465
+ "name": "Agent",
466
+ "outputs": [
467
+ {
468
+ "name": "output",
469
+ "position": "top",
470
+ "type": {
471
+ "type": "None"
472
+ }
473
+ }
474
+ ],
475
+ "params": [
476
+ {
477
+ "default": "",
478
+ "name": "name",
479
+ "type": {
480
+ "type": "<class 'str'>"
481
+ }
482
+ },
483
+ {
484
+ "default": "This agent helps with various tasks.",
485
+ "name": "description",
486
+ "type": {
487
+ "format": "textarea"
488
+ }
489
+ },
490
+ {
491
+ "default": "You are a helpful assistant.",
492
+ "name": "system_prompt",
493
+ "type": {
494
+ "format": "textarea"
495
+ }
496
+ }
497
+ ],
498
+ "type": "basic"
499
+ },
500
+ "op_id": "LynxScribe > Agent",
501
+ "params": {
502
+ "description": "This agent can help with knowledge tasks regarding movies, actors, and financial stocks.",
503
+ "name": "Knowledge agent",
504
+ "system_prompt": "Using the tools at your disposal provide factual answers."
505
+ },
506
+ "status": "done",
507
+ "title": "Agent"
508
+ },
509
+ "dragHandle": ".drag-handle",
510
+ "height": 336.0,
511
+ "id": "Agent 3",
512
+ "position": {
513
+ "x": -194.35714211219977,
514
+ "y": -436.8444624631063
515
+ },
516
+ "type": "basic",
517
+ "width": 497.0
518
+ },
519
+ {
520
+ "data": {
521
+ "__execution_delay": 0.0,
522
+ "display": null,
523
+ "error": null,
524
+ "input_metadata": [
525
+ {}
526
+ ],
527
+ "meta": {
528
+ "categories": [
529
+ "LynxScribe"
530
+ ],
531
+ "color": "blue",
532
+ "doc": null,
533
+ "id": "LynxScribe > Agent",
534
+ "inputs": [
535
+ {
536
+ "name": "tools",
537
+ "position": "bottom",
538
+ "type": {
539
+ "type": "list[dict]"
540
+ }
541
+ }
542
+ ],
543
+ "name": "Agent",
544
+ "outputs": [
545
+ {
546
+ "name": "output",
547
+ "position": "top",
548
+ "type": {
549
+ "type": "None"
550
+ }
551
+ }
552
+ ],
553
+ "params": [
554
+ {
555
+ "default": "",
556
+ "name": "name",
557
+ "type": {
558
+ "type": "<class 'str'>"
559
+ }
560
+ },
561
+ {
562
+ "default": "This agent helps with various tasks.",
563
+ "name": "description",
564
+ "type": {
565
+ "format": "textarea"
566
+ }
567
+ },
568
+ {
569
+ "default": "You are a helpful assistant.",
570
+ "name": "system_prompt",
571
+ "type": {
572
+ "format": "textarea"
573
+ }
574
+ }
575
+ ],
576
+ "type": "basic"
577
+ },
578
+ "op_id": "LynxScribe > Agent",
579
+ "params": {
580
+ "description": "This agent can help with math problems and logic puzzles.",
581
+ "name": "Math agent",
582
+ "system_prompt": "You are a talented mathematician.\nUse the calculator and careful thinking to answer questions.\nAlways check your results and show your work."
583
+ },
584
+ "status": "done",
585
+ "title": "Agent"
586
+ },
587
+ "dragHandle": ".drag-handle",
588
+ "height": 352.0,
589
+ "id": "Agent 4",
590
+ "position": {
591
+ "x": 579.8978751970832,
592
+ "y": -435.69207900433406
593
+ },
594
+ "type": "basic",
595
+ "width": 444.0
596
+ }
597
+ ],
598
+ "paused": false
599
+ }
examples/LynxScribe/MCP/demo.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from lynxkite_core import ops
2
+ from lynxkite_graph_analytics import core
3
+
4
+ lsop = ops.op_registration(
5
+ "LynxKite Graph Analytics", "LynxScribe", dir="bottom-to-top", color="blue"
6
+ )
7
+ dsop = ops.op_registration("LynxKite Graph Analytics", "Data Science")
8
+
9
+
10
+ @lsop("MCP: Query database with SQL", color="green")
11
+ def sql_tool(db: str):
12
+ return {
13
+ "command": ["npx", "-y", "mcp-sqlite", db],
14
+ "extra_prompt": """
15
+ When using the database, retrieve the list of tables, investigate the schema of the relevant tables
16
+ and use SQL queries. Always set a limit of 10 when using `read_records`. Unfortunately, `read_records`
17
+ is out of order currently. Please use `query` instead."
18
+ """.strip(),
19
+ }
20
+
21
+
22
+ @ops.output_position(output="top")
23
+ @dsop("Database")
24
+ def db(data_pipeline: list[core.Bundle]):
25
+ # The source of this file: https://github.com/biggraph/lynxscribe/pull/416
26
+ return "movie_data.sqlite.db"
examples/LynxScribe/MCP/demo.sh ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ #!/bin/bash -xue
2
+ xh POST 'http://localhost:8000/api/service/lynxkite_graph_analytics/LynxScribe%20Task%20Solver/Demo.lynxkite.json/Chat%20frontend%201/chat/completions' \
3
+ model=LynxScribe \
4
+ stream:=false \
5
+ messages:='[{"role": "user", "content": "Investigate the database schema, then use a series of SQL queries to find movies featuring Bette Davis and Ann Sheridan together."}]'
examples/LynxScribe/MCP/ui/main.py ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import requests
3
+
4
+ node_url = st.query_params["service"]
5
+ api_url = f"http://localhost:8000{node_url}"
6
+
7
+ st.title("LynxScribe Task Solver")
8
+
9
+ examples = [
10
+ "Find the value of x given that 4*x^4 = 44.",
11
+ "Which movies feature Bette Davis and Ann Sheridan together? Include the year of the movie's release.",
12
+ "What is the current stock price of Alphabet?",
13
+ "What is the scientific name of Atlantic cod?",
14
+ ]
15
+ selected_example = st.radio("Choose an example:", examples, index=None)
16
+ question = st.text_area(
17
+ "Your question:", value="" if selected_example is None else selected_example
18
+ )
19
+ if question:
20
+ payload = {
21
+ "model": "LynxScribe",
22
+ "stream": False,
23
+ "messages": [{"role": "user", "content": question}],
24
+ }
25
+ response = requests.post(api_url, json=payload)
26
+ if response.ok:
27
+ st.write("\n".join(c["message"]["content"] for c in response.json()["choices"]))
28
+ else:
29
+ st.error(f"Error: {response.status_code}")
examples/LynxScribe/MCP/ui/multi_agent.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import requests
3
+
4
+ API_URL = "http://localhost:8000/api/service/lynxkite_graph_analytics/LynxScribe/MCP/Multi-agent.lynxkite.json/Chat%20frontend%201/chat/completions"
5
+
6
+ st.title("LynxScribe Multi-Agent Example")
7
+
8
+ examples = [
9
+ "Find the value of x given that 4*x^4 = 44.",
10
+ "Which movies feature Bette Davis and Ann Sheridan together? Include the year of the movie's release.",
11
+ "What is the current stock price of Alphabet?",
12
+ "What is the scientific name of Atlantic cod?",
13
+ ]
14
+ selected_example = st.radio("Choose an example:", examples, index=None)
15
+ question = st.text_area(
16
+ "Your question:", value="" if selected_example is None else selected_example
17
+ )
18
+ if question:
19
+ payload = {
20
+ "model": "LynxScribe",
21
+ "stream": False,
22
+ "messages": [{"role": "user", "content": question}],
23
+ }
24
+ response = requests.post(API_URL, json=payload)
25
+ if response.ok:
26
+ st.write("\n".join(c["message"]["content"] for c in response.json()["choices"]))
27
+ else:
28
+ st.error(f"Error: {response.status_code}")
lynxkite-lynxscribe/src/lynxkite_lynxscribe/__init__.py CHANGED
@@ -1,3 +1,4 @@
 
1
  from . import lynxscribe_ops # noqa (imported to trigger registration)
2
  from . import llm_ops # noqa (imported to trigger registration)
3
  from .lynxscribe_ops import api_service_post, api_service_get
 
1
+ from . import agentic # noqa (imported to trigger registration)
2
  from . import lynxscribe_ops # noqa (imported to trigger registration)
3
  from . import llm_ops # noqa (imported to trigger registration)
4
  from .lynxscribe_ops import api_service_post, api_service_get
lynxkite-lynxscribe/src/lynxkite_lynxscribe/agentic.py ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Operations that allow LynxScribe agents and MCP servers to be combined with LynxKite pipelines."""
2
+
3
+ import enum
4
+ import os
5
+ import typing
6
+
7
+ from lynxkite_core import ops
8
+ from lynxscribe.components.task_solver import TaskSolver
9
+ from lynxscribe.components.mcp import MCPClient
10
+ from lynxscribe.core.llm.base import get_llm_engine
11
+ from lynxscribe.core.models.prompts import Function, Tool
12
+
13
+ if typing.TYPE_CHECKING:
14
+ import fastapi
15
+
16
+ CHAT_FRONTEND_URL = os.environ.get("CHAT_FRONTEND_URL", "http://localhost:8501/")
17
+
18
+ op = ops.op_registration(
19
+ "LynxKite Graph Analytics", "LynxScribe", dir="bottom-to-top", color="blue"
20
+ )
21
+
22
+
23
+ @op("Chat frontend", color="gray", outputs=[], view="service")
24
+ def chat_frontend(agent: dict):
25
+ agent = agent["agent"]
26
+ return Agent(
27
+ agent["name"],
28
+ agent["description"],
29
+ agent["system_prompt"],
30
+ agent["mcp_servers"],
31
+ [chat_frontend(a) for a in agent["sub_agents"]],
32
+ )
33
+
34
+
35
+ @op("Agent")
36
+ def agent(
37
+ tools: list[dict],
38
+ *,
39
+ name: str = "",
40
+ description: ops.LongStr = "This agent helps with various tasks.",
41
+ system_prompt: ops.LongStr = "You are a helpful assistant.",
42
+ ):
43
+ prompt = [system_prompt]
44
+ for tool in tools:
45
+ if tool.get("extra_prompt"):
46
+ prompt.append(tool["extra_prompt"])
47
+ return {
48
+ "agent": {
49
+ "name": name,
50
+ "description": description,
51
+ "system_prompt": "\n".join(prompt),
52
+ "mcp_servers": [t["command"] for t in tools if "command" in t],
53
+ "sub_agents": [t for t in tools if "agent" in t],
54
+ }
55
+ }
56
+
57
+
58
+ @op("MCP: Custom", color="green")
59
+ def custom_mcp(*, command: str, extra_prompt: ops.LongStr):
60
+ if command.strip():
61
+ return {"command": command.strip().split(), "extra_prompt": extra_prompt}
62
+
63
+
64
+ # A few basic MCP integrations to serve as examples.
65
+
66
+
67
+ class MCPSearchEngine(str, enum.Enum):
68
+ Google = "Google"
69
+ Bing = "Bing"
70
+ DuckDuckGo = "DuckDuckGo"
71
+
72
+
73
+ @op("MCP: Search web", color="green")
74
+ def web_search(*, engine: MCPSearchEngine = MCPSearchEngine.Google):
75
+ match engine:
76
+ case MCPSearchEngine.Google:
77
+ return {"command": ["npx", "-y", "https://github.com/pskill9/web-search"]}
78
+ case MCPSearchEngine.Bing:
79
+ return {"command": ["uvx", "bing-search-mcp"]}
80
+ case MCPSearchEngine.DuckDuckGo:
81
+ return {"command": ["uvx", "duckduckgo-mcp-server"]}
82
+
83
+
84
+ @op("MCP: Financial data", color="green")
85
+ def financial_data():
86
+ return {"command": ["uvx", "investor-agent"]}
87
+
88
+
89
+ @op("MCP: Calculator", color="green")
90
+ def calculator():
91
+ return {"command": ["uvx", "mcp-server-calculator"]}
92
+
93
+
94
+ @op("MCP: Time", color="green")
95
+ def time():
96
+ return {"command": ["uvx", "mcp-server-time"]}
97
+
98
+
99
+ class Agent:
100
+ def __init__(
101
+ self,
102
+ name: str,
103
+ description: str,
104
+ prompt: str,
105
+ mcp_servers: list[list[str]],
106
+ agents: list["Agent"],
107
+ ):
108
+ self.name = name
109
+ self.description = description
110
+ self.prompt = prompt
111
+ self.mcp_servers = mcp_servers
112
+ self.agents = agents
113
+ self.mcp_client = None
114
+ self.task_solver = None
115
+
116
+ async def init(self):
117
+ if self.task_solver is not None:
118
+ return
119
+ self.mcp_client = MCPClient()
120
+ await self.mcp_client.connect(self.mcp_servers)
121
+ agents_as_functions = [agent.as_function() for agent in self.agents]
122
+ self.task_solver = TaskSolver(
123
+ llm=get_llm_engine(name="openai"),
124
+ model="gpt-4.1-nano",
125
+ initial_messages=[self.prompt],
126
+ functions=[*self.mcp_client.tools, *agents_as_functions],
127
+ tool_choice="required",
128
+ temperature=0.0,
129
+ max_tool_call_steps=999,
130
+ )
131
+
132
+ def get_description(self, url: str) -> str:
133
+ return f"[Go to frontend]({CHAT_FRONTEND_URL}?service={url}/chat/completions)"
134
+
135
+ async def get(self, request: "fastapi.Request") -> dict:
136
+ if request.state.remaining_path == "models":
137
+ return {
138
+ "object": "list",
139
+ "data": [
140
+ {
141
+ "id": "LynxScribe",
142
+ "object": "model",
143
+ "created": 0,
144
+ "owned_by": "lynxkite",
145
+ "meta": {"profile_image_url": "https://lynxkite.com/favicon.png"},
146
+ }
147
+ ],
148
+ }
149
+ return {"error": "Not found"}
150
+
151
+ async def post(self, request: "fastapi.Request") -> dict:
152
+ if request.state.remaining_path == "chat/completions":
153
+ request = await request.json()
154
+ assert not request["stream"]
155
+ await self.init()
156
+ res = await self.task_solver.solve(request["messages"][-1]["content"])
157
+ return {"choices": [{"message": {"role": "assistant", "content": res}}]}
158
+
159
+ return {"error": "Not found"}
160
+
161
+ def as_function(self):
162
+ """A callable that can be used as a tool by another Agent."""
163
+
164
+ # Find the value of x given that 4*x^4 = 44. Compute the numerical value.
165
+ async def ask(message):
166
+ print(f"Calling agent {self.name} with message: {message}")
167
+ await self.init()
168
+ res = await self.task_solver.solve(message)
169
+ print(f"Agent {self.name} response: {res}")
170
+ return res
171
+
172
+ ask.__name__ = "ask_" + self.name.lower().replace(" ", "_")
173
+ ask._tool = Tool(
174
+ type="function",
175
+ function=Function(
176
+ name=ask.__name__,
177
+ description=self.description,
178
+ parameters={
179
+ "type": "object",
180
+ "required": ["message"],
181
+ "properties": {
182
+ "message": {
183
+ "type": "string",
184
+ "description": "The question to ask the agent.",
185
+ }
186
+ },
187
+ },
188
+ ),
189
+ )
190
+ return ask
uv.lock CHANGED
The diff for this file is too large to render. See raw diff