darabos commited on
Commit
16077e8
·
2 Parent(s): 39a1d35 988ca15

Merge remote-tracking branch 'origin/main' into darabos-crdt-updated

Browse files
data/LynxScribe demo ADDED
@@ -0,0 +1,960 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "env": "LynxScribe",
3
+ "nodes": [
4
+ {
5
+ "id": "Input chat 1",
6
+ "type": "basic",
7
+ "data": {
8
+ "title": "Input chat",
9
+ "params": {
10
+ "chat": "who is the CIO of Lynx?"
11
+ },
12
+ "display": null,
13
+ "error": null,
14
+ "meta": {
15
+ "name": "Input chat",
16
+ "params": {
17
+ "chat": {
18
+ "name": "chat",
19
+ "default": null,
20
+ "type": {
21
+ "type": "<class 'str'>"
22
+ }
23
+ }
24
+ },
25
+ "inputs": {},
26
+ "outputs": {
27
+ "output": {
28
+ "name": "output",
29
+ "type": {
30
+ "type": "None"
31
+ },
32
+ "position": "right"
33
+ }
34
+ },
35
+ "type": "basic",
36
+ "sub_nodes": null
37
+ }
38
+ },
39
+ "position": {
40
+ "x": -383.5496596237119,
41
+ "y": 27.567899191800223
42
+ },
43
+ "parentId": null
44
+ },
45
+ {
46
+ "id": "View 1",
47
+ "type": "table_view",
48
+ "data": {
49
+ "title": "View",
50
+ "params": {},
51
+ "display": {
52
+ "dataframes": {
53
+ "df": {
54
+ "columns": [
55
+ "answer"
56
+ ],
57
+ "data": [
58
+ [
59
+ "The Chief Innovation Officer (CIO) of Lynx Analytics is Gabor Benedek. He is responsible for defining the methodological roadmap for the company's predictive analytics consulting and product development departments. If you need more specific information about his role, feel free to ask!\n\nPlease visit <a href='https://www.lynxanalytics.com/team-leadership' target='_blank'>https://www.lynxanalytics.com/team-leadership</a> for further information."
60
+ ]
61
+ ]
62
+ }
63
+ }
64
+ },
65
+ "error": null,
66
+ "meta": {
67
+ "name": "View",
68
+ "params": {},
69
+ "inputs": {
70
+ "input": {
71
+ "name": "input",
72
+ "type": {
73
+ "type": "<class 'inspect._empty'>"
74
+ },
75
+ "position": "left"
76
+ }
77
+ },
78
+ "outputs": {},
79
+ "type": "table_view",
80
+ "sub_nodes": null
81
+ }
82
+ },
83
+ "position": {
84
+ "x": 722.1450069267316,
85
+ "y": -785.6076562320527
86
+ },
87
+ "parentId": null
88
+ },
89
+ {
90
+ "id": "LLM 1",
91
+ "type": "basic",
92
+ "data": {
93
+ "title": "LLM",
94
+ "params": {
95
+ "name": "openai"
96
+ },
97
+ "display": null,
98
+ "error": null,
99
+ "meta": {
100
+ "name": "LLM",
101
+ "params": {
102
+ "name": {
103
+ "name": "name",
104
+ "default": "openai",
105
+ "type": {
106
+ "type": "<class 'str'>"
107
+ }
108
+ }
109
+ },
110
+ "inputs": {},
111
+ "outputs": {
112
+ "output": {
113
+ "name": "output",
114
+ "type": {
115
+ "type": "None"
116
+ },
117
+ "position": "top"
118
+ }
119
+ },
120
+ "type": "basic",
121
+ "sub_nodes": null
122
+ }
123
+ },
124
+ "position": {
125
+ "x": -312.5774211084781,
126
+ "y": 1093.4019527511366
127
+ },
128
+ "parentId": null
129
+ },
130
+ {
131
+ "id": "Scenario selector 1",
132
+ "type": "basic",
133
+ "data": {
134
+ "title": "Scenario selector",
135
+ "params": {
136
+ "scenario_file": "/home/darabos/nvme/lynxscribe/examples/chat_api/scenarios.yaml",
137
+ "node_types": "intent_cluster"
138
+ },
139
+ "display": null,
140
+ "error": null,
141
+ "meta": {
142
+ "name": "Scenario selector",
143
+ "params": {
144
+ "scenario_file": {
145
+ "name": "scenario_file",
146
+ "default": null,
147
+ "type": {
148
+ "type": "<class 'str'>"
149
+ }
150
+ },
151
+ "node_types": {
152
+ "name": "node_types",
153
+ "default": "intent_cluster",
154
+ "type": {
155
+ "type": "<class 'str'>"
156
+ }
157
+ }
158
+ },
159
+ "inputs": {},
160
+ "outputs": {
161
+ "output": {
162
+ "name": "output",
163
+ "type": {
164
+ "type": "None"
165
+ },
166
+ "position": "top"
167
+ }
168
+ },
169
+ "type": "basic",
170
+ "sub_nodes": null
171
+ }
172
+ },
173
+ "position": {
174
+ "x": -549.1300345090008,
175
+ "y": 1086.4852248156676
176
+ },
177
+ "parentId": null
178
+ },
179
+ {
180
+ "id": "Chat API 1",
181
+ "type": "basic",
182
+ "data": {
183
+ "title": "Chat API",
184
+ "params": {
185
+ "model": "gpt-4o-mini"
186
+ },
187
+ "display": null,
188
+ "error": null,
189
+ "meta": {
190
+ "name": "Chat API",
191
+ "params": {
192
+ "model": {
193
+ "name": "model",
194
+ "default": "gpt-4o-mini",
195
+ "type": {
196
+ "type": "<class 'str'>"
197
+ }
198
+ }
199
+ },
200
+ "inputs": {
201
+ "chatbot": {
202
+ "name": "chatbot",
203
+ "type": {
204
+ "type": "<class 'inspect._empty'>"
205
+ },
206
+ "position": "bottom"
207
+ },
208
+ "chat_processor": {
209
+ "name": "chat_processor",
210
+ "type": {
211
+ "type": "<class 'inspect._empty'>"
212
+ },
213
+ "position": "bottom"
214
+ },
215
+ "knowledge_base": {
216
+ "name": "knowledge_base",
217
+ "type": {
218
+ "type": "<class 'inspect._empty'>"
219
+ },
220
+ "position": "bottom"
221
+ }
222
+ },
223
+ "outputs": {
224
+ "output": {
225
+ "name": "output",
226
+ "type": {
227
+ "type": "None"
228
+ },
229
+ "position": "top"
230
+ }
231
+ },
232
+ "type": "basic",
233
+ "sub_nodes": null
234
+ }
235
+ },
236
+ "position": {
237
+ "x": -22.866663363810787,
238
+ "y": 258.20943122219336
239
+ },
240
+ "parentId": null
241
+ },
242
+ {
243
+ "id": "Knowledge base 1",
244
+ "type": "basic",
245
+ "data": {
246
+ "title": "Knowledge base",
247
+ "params": {
248
+ "nodes_path": "/home/darabos/nvme/lynxscribe/examples/chat_api/data/lynx/nodes.pickle",
249
+ "edges_path": "/home/darabos/nvme/lynxscribe/examples/chat_api/data/lynx/edges.pickle",
250
+ "template_cluster_path": "/home/darabos/nvme/lynxscribe/examples/chat_api/data/lynx/tempclusters.pickle"
251
+ },
252
+ "display": null,
253
+ "error": null,
254
+ "meta": {
255
+ "name": "Knowledge base",
256
+ "params": {
257
+ "nodes_path": {
258
+ "name": "nodes_path",
259
+ "default": "nodes.pickle",
260
+ "type": {
261
+ "type": "<class 'str'>"
262
+ }
263
+ },
264
+ "edges_path": {
265
+ "name": "edges_path",
266
+ "default": "edges.pickle",
267
+ "type": {
268
+ "type": "<class 'str'>"
269
+ }
270
+ },
271
+ "template_cluster_path": {
272
+ "name": "template_cluster_path",
273
+ "default": "tempclusters.pickle",
274
+ "type": {
275
+ "type": "<class 'str'>"
276
+ }
277
+ }
278
+ },
279
+ "inputs": {},
280
+ "outputs": {
281
+ "output": {
282
+ "name": "output",
283
+ "type": {
284
+ "type": "None"
285
+ },
286
+ "position": "top"
287
+ }
288
+ },
289
+ "type": "basic",
290
+ "sub_nodes": null
291
+ }
292
+ },
293
+ "position": {
294
+ "x": 382.20164582795104,
295
+ "y": 533.2833307141879
296
+ },
297
+ "parentId": null
298
+ },
299
+ {
300
+ "id": "RAG chatbot 1",
301
+ "type": "basic",
302
+ "data": {
303
+ "title": "RAG chatbot",
304
+ "params": {
305
+ "negative_answer": "I'm sorry, but the data I've been trained on does not contain any information related to your question.",
306
+ "limits_by_type": "{\"information\": [2, 3], \"summary\": [2, 3]}",
307
+ "strict_limits": true,
308
+ "max_results": "5"
309
+ },
310
+ "display": null,
311
+ "error": null,
312
+ "meta": {
313
+ "name": "RAG chatbot",
314
+ "params": {
315
+ "negative_answer": {
316
+ "name": "negative_answer",
317
+ "default": "I'm sorry, but the data I've been trained on does not contain any information related to your question.",
318
+ "type": {
319
+ "type": "<class 'str'>"
320
+ }
321
+ },
322
+ "limits_by_type": {
323
+ "name": "limits_by_type",
324
+ "default": "{}",
325
+ "type": {
326
+ "type": "<class 'str'>"
327
+ }
328
+ },
329
+ "strict_limits": {
330
+ "name": "strict_limits",
331
+ "default": true,
332
+ "type": {
333
+ "type": "<class 'bool'>"
334
+ }
335
+ },
336
+ "max_results": {
337
+ "name": "max_results",
338
+ "default": 5,
339
+ "type": {
340
+ "type": "<class 'int'>"
341
+ }
342
+ }
343
+ },
344
+ "inputs": {
345
+ "rag_graph": {
346
+ "name": "rag_graph",
347
+ "type": {
348
+ "type": "<class 'inspect._empty'>"
349
+ },
350
+ "position": "bottom"
351
+ },
352
+ "scenario_selector": {
353
+ "name": "scenario_selector",
354
+ "type": {
355
+ "type": "<class 'inspect._empty'>"
356
+ },
357
+ "position": "bottom"
358
+ },
359
+ "llm": {
360
+ "name": "llm",
361
+ "type": {
362
+ "type": "<class 'inspect._empty'>"
363
+ },
364
+ "position": "bottom"
365
+ }
366
+ },
367
+ "outputs": {
368
+ "output": {
369
+ "name": "output",
370
+ "type": {
371
+ "type": "None"
372
+ },
373
+ "position": "top"
374
+ }
375
+ },
376
+ "type": "basic",
377
+ "sub_nodes": null
378
+ },
379
+ "beingResized": false
380
+ },
381
+ "position": {
382
+ "x": -533.1301830766971,
383
+ "y": 547.294980747757
384
+ },
385
+ "parentId": null,
386
+ "width": 336,
387
+ "height": 349
388
+ },
389
+ {
390
+ "id": "RAG graph 1",
391
+ "type": "basic",
392
+ "data": {
393
+ "title": "RAG graph",
394
+ "params": {},
395
+ "display": null,
396
+ "error": null,
397
+ "meta": {
398
+ "name": "RAG graph",
399
+ "params": {},
400
+ "inputs": {
401
+ "vector_store": {
402
+ "name": "vector_store",
403
+ "type": {
404
+ "type": "<class 'inspect._empty'>"
405
+ },
406
+ "position": "bottom"
407
+ },
408
+ "text_embedder": {
409
+ "name": "text_embedder",
410
+ "type": {
411
+ "type": "<class 'inspect._empty'>"
412
+ },
413
+ "position": "bottom"
414
+ }
415
+ },
416
+ "outputs": {
417
+ "output": {
418
+ "name": "output",
419
+ "type": {
420
+ "type": "None"
421
+ },
422
+ "position": "top"
423
+ }
424
+ },
425
+ "type": "basic",
426
+ "sub_nodes": null
427
+ }
428
+ },
429
+ "position": {
430
+ "x": -817.8208895639339,
431
+ "y": 1014.836542916127
432
+ },
433
+ "parentId": null
434
+ },
435
+ {
436
+ "id": "Vector store 1",
437
+ "type": "basic",
438
+ "data": {
439
+ "title": "Vector store",
440
+ "params": {
441
+ "name": "chromadb",
442
+ "collection_name": "lynx"
443
+ },
444
+ "display": null,
445
+ "error": null,
446
+ "meta": {
447
+ "name": "Vector store",
448
+ "params": {
449
+ "name": {
450
+ "name": "name",
451
+ "default": "chromadb",
452
+ "type": {
453
+ "type": "<class 'str'>"
454
+ }
455
+ },
456
+ "collection_name": {
457
+ "name": "collection_name",
458
+ "default": "lynx",
459
+ "type": {
460
+ "type": "<class 'str'>"
461
+ }
462
+ }
463
+ },
464
+ "inputs": {},
465
+ "outputs": {
466
+ "output": {
467
+ "name": "output",
468
+ "type": {
469
+ "type": "None"
470
+ },
471
+ "position": "top"
472
+ }
473
+ },
474
+ "type": "basic",
475
+ "sub_nodes": null
476
+ },
477
+ "beingResized": false
478
+ },
479
+ "position": {
480
+ "x": -1053.794625339574,
481
+ "y": 1347.7711940497127
482
+ },
483
+ "parentId": null,
484
+ "width": 275,
485
+ "height": 227
486
+ },
487
+ {
488
+ "id": "Text embedder 2",
489
+ "type": "basic",
490
+ "data": {
491
+ "title": "Text embedder",
492
+ "params": {
493
+ "model": "text-embedding-ada-002"
494
+ },
495
+ "display": null,
496
+ "error": null,
497
+ "meta": {
498
+ "name": "Text embedder",
499
+ "params": {
500
+ "model": {
501
+ "name": "model",
502
+ "default": "text-embedding-ada-002",
503
+ "type": {
504
+ "type": "<class 'str'>"
505
+ }
506
+ }
507
+ },
508
+ "inputs": {
509
+ "llm": {
510
+ "name": "llm",
511
+ "type": {
512
+ "type": "<class 'inspect._empty'>"
513
+ },
514
+ "position": "bottom"
515
+ }
516
+ },
517
+ "outputs": {
518
+ "output": {
519
+ "name": "output",
520
+ "type": {
521
+ "type": "None"
522
+ },
523
+ "position": "top"
524
+ }
525
+ },
526
+ "type": "basic",
527
+ "sub_nodes": null
528
+ }
529
+ },
530
+ "position": {
531
+ "x": -749.98604638686,
532
+ "y": 1293.5978526690794
533
+ },
534
+ "parentId": null
535
+ },
536
+ {
537
+ "id": "LLM 2",
538
+ "type": "basic",
539
+ "data": {
540
+ "title": "LLM",
541
+ "params": {
542
+ "name": "openai"
543
+ },
544
+ "display": null,
545
+ "error": null,
546
+ "meta": {
547
+ "name": "LLM",
548
+ "params": {
549
+ "name": {
550
+ "name": "name",
551
+ "default": "openai",
552
+ "type": {
553
+ "type": "<class 'str'>"
554
+ }
555
+ }
556
+ },
557
+ "inputs": {},
558
+ "outputs": {
559
+ "output": {
560
+ "name": "output",
561
+ "type": {
562
+ "type": "None"
563
+ },
564
+ "position": "top"
565
+ }
566
+ },
567
+ "type": "basic",
568
+ "sub_nodes": null
569
+ }
570
+ },
571
+ "position": {
572
+ "x": -714.2838040349482,
573
+ "y": 1469.7242636905507
574
+ },
575
+ "parentId": null
576
+ },
577
+ {
578
+ "id": "Truncate history 1",
579
+ "type": "basic",
580
+ "data": {
581
+ "title": "Truncate history",
582
+ "params": {
583
+ "max_tokens": 10000,
584
+ "language": "English"
585
+ },
586
+ "display": null,
587
+ "error": null,
588
+ "meta": {
589
+ "name": "Truncate history",
590
+ "params": {
591
+ "max_tokens": {
592
+ "name": "max_tokens",
593
+ "default": 10000,
594
+ "type": {
595
+ "type": "<class 'int'>"
596
+ }
597
+ },
598
+ "language": {
599
+ "name": "language",
600
+ "default": "English",
601
+ "type": {
602
+ "type": "<class 'str'>"
603
+ }
604
+ }
605
+ },
606
+ "inputs": {},
607
+ "outputs": {
608
+ "output": {
609
+ "name": "output",
610
+ "type": {
611
+ "type": "None"
612
+ },
613
+ "position": "top"
614
+ }
615
+ },
616
+ "type": "basic",
617
+ "sub_nodes": null
618
+ }
619
+ },
620
+ "position": {
621
+ "x": 0.08889822620079713,
622
+ "y": 1044.7639853229612
623
+ },
624
+ "parentId": null
625
+ },
626
+ {
627
+ "id": "Chat processor 1",
628
+ "type": "basic",
629
+ "data": {
630
+ "title": "Chat processor",
631
+ "params": {},
632
+ "display": null,
633
+ "error": null,
634
+ "meta": {
635
+ "name": "Chat processor",
636
+ "params": {},
637
+ "inputs": {
638
+ "processor": {
639
+ "name": "processor",
640
+ "type": {
641
+ "type": "<class 'inspect._empty'>"
642
+ },
643
+ "position": "bottom"
644
+ }
645
+ },
646
+ "outputs": {
647
+ "output": {
648
+ "name": "output",
649
+ "type": {
650
+ "type": "None"
651
+ },
652
+ "position": "top"
653
+ }
654
+ },
655
+ "type": "basic",
656
+ "sub_nodes": null
657
+ }
658
+ },
659
+ "position": {
660
+ "x": 266.23062579739207,
661
+ "y": 931.8796075565143
662
+ },
663
+ "parentId": null
664
+ },
665
+ {
666
+ "id": "Mask 1",
667
+ "type": "basic",
668
+ "data": {
669
+ "title": "Mask",
670
+ "params": {
671
+ "name": "email",
672
+ "regex": "([a-z0-9!#$%&'*+\\/=?^_`{|.}~-]+@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)",
673
674
+ "mask_pattern": "masked_email_address_{}"
675
+ },
676
+ "display": null,
677
+ "error": null,
678
+ "meta": {
679
+ "name": "Mask",
680
+ "params": {
681
+ "name": {
682
+ "name": "name",
683
+ "default": "",
684
+ "type": {
685
+ "type": "<class 'str'>"
686
+ }
687
+ },
688
+ "regex": {
689
+ "name": "regex",
690
+ "default": "",
691
+ "type": {
692
+ "type": "<class 'str'>"
693
+ }
694
+ },
695
+ "exceptions": {
696
+ "name": "exceptions",
697
+ "default": "",
698
+ "type": {
699
+ "type": "<class 'str'>"
700
+ }
701
+ },
702
+ "mask_pattern": {
703
+ "name": "mask_pattern",
704
+ "default": "",
705
+ "type": {
706
+ "type": "<class 'str'>"
707
+ }
708
+ }
709
+ },
710
+ "inputs": {},
711
+ "outputs": {
712
+ "output": {
713
+ "name": "output",
714
+ "type": {
715
+ "type": "None"
716
+ },
717
+ "position": "top"
718
+ }
719
+ },
720
+ "type": "basic",
721
+ "sub_nodes": null
722
+ }
723
+ },
724
+ "position": {
725
+ "x": 233.69759202223884,
726
+ "y": 1041.6145468043276
727
+ },
728
+ "parentId": null
729
+ },
730
+ {
731
+ "id": "Mask 2",
732
+ "type": "basic",
733
+ "data": {
734
+ "title": "Mask",
735
+ "params": {
736
+ "name": "credit_card",
737
+ "regex": "((?:(?:\\\\d{4}[- ]?){3}\\\\d{4}|\\\\d{15,16}))(?![\\\\d])",
738
+ "exceptions": "",
739
+ "mask_pattern": "masked_credit_card_number_{}"
740
+ },
741
+ "display": null,
742
+ "error": null,
743
+ "meta": {
744
+ "name": "Mask",
745
+ "params": {
746
+ "name": {
747
+ "name": "name",
748
+ "default": "",
749
+ "type": {
750
+ "type": "<class 'str'>"
751
+ }
752
+ },
753
+ "regex": {
754
+ "name": "regex",
755
+ "default": "",
756
+ "type": {
757
+ "type": "<class 'str'>"
758
+ }
759
+ },
760
+ "exceptions": {
761
+ "name": "exceptions",
762
+ "default": "",
763
+ "type": {
764
+ "type": "<class 'str'>"
765
+ }
766
+ },
767
+ "mask_pattern": {
768
+ "name": "mask_pattern",
769
+ "default": "",
770
+ "type": {
771
+ "type": "<class 'str'>"
772
+ }
773
+ }
774
+ },
775
+ "inputs": {},
776
+ "outputs": {
777
+ "output": {
778
+ "name": "output",
779
+ "type": {
780
+ "type": "None"
781
+ },
782
+ "position": "top"
783
+ }
784
+ },
785
+ "type": "basic",
786
+ "sub_nodes": null
787
+ }
788
+ },
789
+ "position": {
790
+ "x": 513.2761671440603,
791
+ "y": 1034.8547191984255
792
+ },
793
+ "parentId": null
794
+ },
795
+ {
796
+ "id": "Test Chat API 2",
797
+ "type": "basic",
798
+ "data": {
799
+ "title": "Test Chat API",
800
+ "params": {
801
+ "show_details": false
802
+ },
803
+ "display": null,
804
+ "error": null,
805
+ "meta": {
806
+ "name": "Test Chat API",
807
+ "params": {
808
+ "show_details": {
809
+ "name": "show_details",
810
+ "default": false,
811
+ "type": {
812
+ "type": "<class 'bool'>"
813
+ }
814
+ }
815
+ },
816
+ "inputs": {
817
+ "message": {
818
+ "name": "message",
819
+ "type": {
820
+ "type": "<class 'inspect._empty'>"
821
+ },
822
+ "position": "left"
823
+ },
824
+ "chat_api": {
825
+ "name": "chat_api",
826
+ "type": {
827
+ "type": "<class 'inspect._empty'>"
828
+ },
829
+ "position": "bottom"
830
+ }
831
+ },
832
+ "outputs": {
833
+ "output": {
834
+ "name": "output",
835
+ "type": {
836
+ "type": "None"
837
+ },
838
+ "position": "right"
839
+ }
840
+ },
841
+ "type": "basic",
842
+ "sub_nodes": null
843
+ },
844
+ "collapsed": false
845
+ },
846
+ "position": {
847
+ "x": -11.653333595036415,
848
+ "y": -0.9210389517918429
849
+ },
850
+ "parentId": null
851
+ }
852
+ ],
853
+ "edges": [
854
+ {
855
+ "id": "xy-edge__Knowledge base 1output-Chat API 1knowledge_base",
856
+ "source": "Knowledge base 1",
857
+ "target": "Chat API 1",
858
+ "sourceHandle": "output",
859
+ "targetHandle": "knowledge_base"
860
+ },
861
+ {
862
+ "id": "xy-edge__RAG chatbot 1output-Chat API 1chatbot",
863
+ "source": "RAG chatbot 1",
864
+ "target": "Chat API 1",
865
+ "sourceHandle": "output",
866
+ "targetHandle": "chatbot"
867
+ },
868
+ {
869
+ "id": "xy-edge__LLM 1output-RAG chatbot 1llm",
870
+ "source": "LLM 1",
871
+ "target": "RAG chatbot 1",
872
+ "sourceHandle": "output",
873
+ "targetHandle": "llm"
874
+ },
875
+ {
876
+ "id": "xy-edge__Scenario selector 1output-RAG chatbot 1scenario_selector",
877
+ "source": "Scenario selector 1",
878
+ "target": "RAG chatbot 1",
879
+ "sourceHandle": "output",
880
+ "targetHandle": "scenario_selector"
881
+ },
882
+ {
883
+ "id": "xy-edge__RAG graph 1output-RAG chatbot 1rag_graph",
884
+ "source": "RAG graph 1",
885
+ "target": "RAG chatbot 1",
886
+ "sourceHandle": "output",
887
+ "targetHandle": "rag_graph"
888
+ },
889
+ {
890
+ "id": "xy-edge__Vector store 1output-RAG graph 1vector_store",
891
+ "source": "Vector store 1",
892
+ "target": "RAG graph 1",
893
+ "sourceHandle": "output",
894
+ "targetHandle": "vector_store"
895
+ },
896
+ {
897
+ "id": "xy-edge__Text embedder 2output-RAG graph 1text_embedder",
898
+ "source": "Text embedder 2",
899
+ "target": "RAG graph 1",
900
+ "sourceHandle": "output",
901
+ "targetHandle": "text_embedder"
902
+ },
903
+ {
904
+ "id": "xy-edge__LLM 2output-Text embedder 2llm",
905
+ "source": "LLM 2",
906
+ "target": "Text embedder 2",
907
+ "sourceHandle": "output",
908
+ "targetHandle": "llm"
909
+ },
910
+ {
911
+ "id": "xy-edge__Truncate history 1output-Chat processor 1processor",
912
+ "source": "Truncate history 1",
913
+ "target": "Chat processor 1",
914
+ "sourceHandle": "output",
915
+ "targetHandle": "processor"
916
+ },
917
+ {
918
+ "id": "xy-edge__Chat processor 1output-Chat API 1chat_processor",
919
+ "source": "Chat processor 1",
920
+ "target": "Chat API 1",
921
+ "sourceHandle": "output",
922
+ "targetHandle": "chat_processor"
923
+ },
924
+ {
925
+ "id": "xy-edge__Mask 1output-Chat processor 1processor",
926
+ "source": "Mask 1",
927
+ "target": "Chat processor 1",
928
+ "sourceHandle": "output",
929
+ "targetHandle": "processor"
930
+ },
931
+ {
932
+ "id": "xy-edge__Mask 2output-Chat processor 1processor",
933
+ "source": "Mask 2",
934
+ "target": "Chat processor 1",
935
+ "sourceHandle": "output",
936
+ "targetHandle": "processor"
937
+ },
938
+ {
939
+ "id": "xy-edge__Input chat 1output-Test Chat API 2message",
940
+ "source": "Input chat 1",
941
+ "target": "Test Chat API 2",
942
+ "sourceHandle": "output",
943
+ "targetHandle": "message"
944
+ },
945
+ {
946
+ "id": "xy-edge__Test Chat API 2output-View 1input",
947
+ "source": "Test Chat API 2",
948
+ "target": "View 1",
949
+ "sourceHandle": "output",
950
+ "targetHandle": "input"
951
+ },
952
+ {
953
+ "id": "xy-edge__Chat API 1output-Test Chat API 2chat_api",
954
+ "source": "Chat API 1",
955
+ "target": "Test Chat API 2",
956
+ "sourceHandle": "output",
957
+ "targetHandle": "chat_api"
958
+ }
959
+ ]
960
+ }
requirements.txt CHANGED
@@ -2,6 +2,7 @@ fastapi
2
  matplotlib
3
  networkx
4
  numpy
 
5
  pandas
6
  scipy
7
  uvicorn[standard]
 
2
  matplotlib
3
  networkx
4
  numpy
5
+ orjson
6
  pandas
7
  scipy
8
  uvicorn[standard]
server/executors/one_by_one.py CHANGED
@@ -1,8 +1,8 @@
1
  from .. import ops
2
  from .. import workspace
3
- import fastapi
4
- import json
5
  import pandas as pd
 
6
  import traceback
7
  import inspect
8
  import typing
@@ -37,7 +37,7 @@ def register(env: str, cache: bool = True):
37
  ops.EXECUTORS[env] = lambda ws: execute(ws, ops.CATALOGS[env], cache=cache)
38
 
39
  def get_stages(ws, catalog):
40
- '''Inputs on top are batch inputs. We decompose the graph into a DAG of components along these edges.'''
41
  nodes = {n.id: n for n in ws.nodes}
42
  batch_inputs = {}
43
  inputs = {}
@@ -46,7 +46,7 @@ def get_stages(ws, catalog):
46
  node = nodes[edge.target]
47
  op = catalog[node.data.title]
48
  i = op.inputs[edge.targetHandle]
49
- if i.position == 'top':
50
  batch_inputs.setdefault(edge.target, []).append(edge.source)
51
  stages = []
52
  for bt, bss in batch_inputs.items():
@@ -63,6 +63,15 @@ def get_stages(ws, catalog):
63
  stages.append(set(nodes))
64
  return stages
65
 
 
 
 
 
 
 
 
 
 
66
  EXECUTOR_OUTPUT_CACHE = {}
67
 
68
  def execute(ws, catalog, cache=None):
@@ -77,7 +86,7 @@ def execute(ws, catalog, cache=None):
77
  node.data.error = None
78
  op = catalog[node.data.title]
79
  # Start tasks for nodes that have no non-batch inputs.
80
- if all([i.position == 'top' for i in op.inputs.values()]):
81
  tasks[node.id] = [NO_INPUT]
82
  batch_inputs = {}
83
  # Run the rest until we run out of tasks.
@@ -99,12 +108,12 @@ def execute(ws, catalog, cache=None):
99
  for task in ts:
100
  try:
101
  inputs = [
102
- batch_inputs[(n, i.name)] if i.position == 'top' else task
103
  for i in op.inputs.values()]
104
- if cache:
105
- key = json.dumps(fastapi.encoders.jsonable_encoder((inputs, params)))
106
  if key not in cache:
107
- cache[key] = op.func(*inputs, **params)
108
  result = cache[key]
109
  else:
110
  result = op(*inputs, **params)
@@ -126,8 +135,9 @@ def execute(ws, catalog, cache=None):
126
  t = nodes[edge.target]
127
  op = catalog[t.data.title]
128
  i = op.inputs[edge.targetHandle]
129
- if i.position == 'top':
130
  batch_inputs.setdefault((edge.target, edge.targetHandle), []).extend(results)
131
  else:
132
  tasks.setdefault(edge.target, []).extend(results)
133
  tasks = next_stage
 
 
1
  from .. import ops
2
  from .. import workspace
3
+ import orjson
 
4
  import pandas as pd
5
+ import pydantic
6
  import traceback
7
  import inspect
8
  import typing
 
37
  ops.EXECUTORS[env] = lambda ws: execute(ws, ops.CATALOGS[env], cache=cache)
38
 
39
  def get_stages(ws, catalog):
40
+ '''Inputs on top/bottom are batch inputs. We decompose the graph into a DAG of components along these edges.'''
41
  nodes = {n.id: n for n in ws.nodes}
42
  batch_inputs = {}
43
  inputs = {}
 
46
  node = nodes[edge.target]
47
  op = catalog[node.data.title]
48
  i = op.inputs[edge.targetHandle]
49
+ if i.position in 'top or bottom':
50
  batch_inputs.setdefault(edge.target, []).append(edge.source)
51
  stages = []
52
  for bt, bss in batch_inputs.items():
 
63
  stages.append(set(nodes))
64
  return stages
65
 
66
+
67
+ def _default_serializer(obj):
68
+ if isinstance(obj, pydantic.BaseModel):
69
+ return obj.dict()
70
+ return {"__nonserializable__": id(obj)}
71
+
72
+ def make_cache_key(obj):
73
+ return orjson.dumps(obj, default=_default_serializer)
74
+
75
  EXECUTOR_OUTPUT_CACHE = {}
76
 
77
  def execute(ws, catalog, cache=None):
 
86
  node.data.error = None
87
  op = catalog[node.data.title]
88
  # Start tasks for nodes that have no non-batch inputs.
89
+ if all([i.position in 'top or bottom' for i in op.inputs.values()]):
90
  tasks[node.id] = [NO_INPUT]
91
  batch_inputs = {}
92
  # Run the rest until we run out of tasks.
 
108
  for task in ts:
109
  try:
110
  inputs = [
111
+ batch_inputs[(n, i.name)] if i.position in 'top or bottom' else task
112
  for i in op.inputs.values()]
113
+ if cache is not None:
114
+ key = make_cache_key((inputs, params))
115
  if key not in cache:
116
+ cache[key] = op(*inputs, **params)
117
  result = cache[key]
118
  else:
119
  result = op(*inputs, **params)
 
135
  t = nodes[edge.target]
136
  op = catalog[t.data.title]
137
  i = op.inputs[edge.targetHandle]
138
+ if i.position in 'top or bottom':
139
  batch_inputs.setdefault((edge.target, edge.targetHandle), []).extend(results)
140
  else:
141
  tasks.setdefault(edge.target, []).extend(results)
142
  tasks = next_stage
143
+ return contexts
server/lynxscribe_ops.py CHANGED
@@ -1,52 +1,203 @@
1
- '''An example of passive ops. Just using LynxKite to describe the configuration of a complex system.'''
2
- from .ops import passive_op_registration, Parameter as P, MULTI_INPUT
3
-
4
- reg = passive_op_registration('LynxScribe')
5
- reg('Scrape documents', params=[P.basic('url', '')])
6
- reg('Conversation logs')
7
- reg('Extract graph', inputs=['input'])
8
- reg('Compute embeddings', inputs=['input'], params=[P.options('method', ['OpenAI', 'graph', 'Yi-34b']), P.basic('dimensions', 1234)])
9
- reg('Vector DB', inputs=[MULTI_INPUT], params=[P.options('backend', ['FAISS', 'ANN', 'HNSW'])])
10
- reg('Chat UI', outputs=[], inputs=['input'])
11
- reg('Chat backend')
12
- reg('WhatsApp')
13
- reg('PII removal', inputs=['input'])
14
- reg('Intent classification', inputs=['input'])
15
- reg('System prompt', params=[P.basic('prompt', 'You are a helpful chatbot.')])
16
- reg('LLM', inputs=[MULTI_INPUT], params=[P.options('backend', ['GPT-4', 'Yi-34b', 'Claude 3 Opus', 'Google Gemini'])])
17
-
18
- # From Marton's mock-up.
19
- yi = 'Yi-34B (triton)'
20
- reg('Chat Input', params=[
21
- P.options('load_mode', ['augmented']),
22
- P.options('model', [yi]),
23
- P.options('embedder', ['GritLM-7b (triton)']),
24
- ])
25
- reg('k-NN Intent Classifier', inputs=['qa_embs', 'rag_graph'], params=[
26
- P.options('distance', ['cosine', 'euclidean']),
27
- P.basic('max_dist', 0.3),
28
- P.basic('k', 3),
29
- P.options('voting', ['most common', 'weighted']),
30
- ])
31
- reg('Chroma Graph RAG Loader', inputs=[], params=[
32
- P.options('location', ['GCP']),
33
- P.collapsed('bucket', ''),
34
- P.collapsed('folder', ''),
35
- P.options('embedder', ['GritLM-7b (triton)']),
36
- ])
37
- reg('Scenario Builder', inputs=['input'], params=[
38
- P.collapsed('scenario', ''),
39
- ])
40
- reg('Graph RAG Answer', inputs=['qa_embs', 'intent', 'rag_graph', 'prompt_dict'], params=[
41
- P.options('answer_llm', [yi]),
42
- P.basic('faq_dist', 0.12),
43
- P.basic('max_dist', 0.25),
44
- P.basic('ctx_tokens', 2800),
45
- P.options('distance', ['cosine', 'euclidean']),
46
- P.collapsed('graph_rag_params', ''),
47
- ])
48
- reg('Answer Post Processing', inputs=['qa_embs', 'rag_graph'], params=[
49
- P.options('distance', ['cosine', 'euclidean']),
50
- P.basic('min_conf', 0.78),
51
- ])
52
- reg('Chat Output', inputs=['input'], outputs=[])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ LynxScribe configuration and testing in LynxKite.
3
+ """
4
+ from lynxscribe.core.llm.base import get_llm_engine
5
+ from lynxscribe.core.vector_store.base import get_vector_store
6
+ from lynxscribe.common.config import load_config
7
+ from lynxscribe.components.text_embedder import TextEmbedder
8
+ from lynxscribe.components.rag.rag_graph import RAGGraph
9
+ from lynxscribe.components.rag.knowledge_base_graph import PandasKnowledgeBaseGraph
10
+ from lynxscribe.components.rag.rag_chatbot import Scenario, ScenarioSelector, RAGChatbot
11
+ from lynxscribe.components.chat_processor.base import ChatProcessor
12
+ from lynxscribe.components.chat_processor.processors import MaskTemplate, TruncateHistory
13
+ from lynxscribe.components.chat_api import ChatAPI, ChatAPIRequest, ChatAPIResponse
14
+
15
+ from . import ops
16
+ import asyncio
17
+ import json
18
+ from .executors import one_by_one
19
+
20
+ ENV = 'LynxScribe'
21
+ one_by_one.register(ENV)
22
+ op = ops.op_registration(ENV)
23
+ output_on_top = ops.output_position(output="top")
24
+
25
+ @output_on_top
26
+ @op("Vector store")
27
+ def vector_store(*, name='chromadb', collection_name='lynx'):
28
+ vector_store = get_vector_store(name=name, collection_name=collection_name)
29
+ return {'vector_store': vector_store}
30
+
31
+ @output_on_top
32
+ @op("LLM")
33
+ def llm(*, name='openai'):
34
+ llm = get_llm_engine(name=name)
35
+ return {'llm': llm}
36
+
37
+ @output_on_top
38
+ @ops.input_position(llm="bottom")
39
+ @op("Text embedder")
40
+ def text_embedder(llm, *, model='text-embedding-ada-002'):
41
+ llm = llm[0]['llm']
42
+ text_embedder = TextEmbedder(llm=llm, model=model)
43
+ return {'text_embedder': text_embedder}
44
+
45
+ @output_on_top
46
+ @ops.input_position(vector_store="bottom", text_embedder="bottom")
47
+ @op("RAG graph")
48
+ def rag_graph(vector_store, text_embedder):
49
+ vector_store = vector_store[0]['vector_store']
50
+ text_embedder = text_embedder[0]['text_embedder']
51
+ rag_graph = RAGGraph(
52
+ PandasKnowledgeBaseGraph(vector_store=vector_store, text_embedder=text_embedder)
53
+ )
54
+ return {'rag_graph': rag_graph}
55
+
56
+ @output_on_top
57
+ @op("Scenario selector")
58
+ def scenario_selector(*, scenario_file: str, node_types='intent_cluster'):
59
+ scenarios = load_config(scenario_file)
60
+ node_types = [t.strip() for t in node_types.split(',')]
61
+ scenario_selector = ScenarioSelector(
62
+ scenarios=[Scenario(**scenario) for scenario in scenarios],
63
+ node_types=node_types,
64
+ )
65
+ return {'scenario_selector': scenario_selector}
66
+
67
+ DEFAULT_NEGATIVE_ANSWER = "I'm sorry, but the data I've been trained on does not contain any information related to your question."
68
+
69
+ @output_on_top
70
+ @ops.input_position(rag_graph="bottom", scenario_selector="bottom", llm="bottom")
71
+ @op("RAG chatbot")
72
+ def rag_chatbot(
73
+ rag_graph, scenario_selector, llm, *,
74
+ negative_answer=DEFAULT_NEGATIVE_ANSWER,
75
+ limits_by_type='{}',
76
+ strict_limits=True, max_results=5):
77
+ rag_graph = rag_graph[0]['rag_graph']
78
+ scenario_selector = scenario_selector[0]['scenario_selector']
79
+ llm = llm[0]['llm']
80
+ limits_by_type = json.loads(limits_by_type)
81
+ rag_chatbot = RAGChatbot(
82
+ rag_graph=rag_graph,
83
+ scenario_selector=scenario_selector,
84
+ llm=llm,
85
+ negative_answer=negative_answer,
86
+ limits_by_type=limits_by_type,
87
+ strict_limits=strict_limits,
88
+ max_results=max_results,
89
+ )
90
+ return {'chatbot': rag_chatbot}
91
+
92
+ @output_on_top
93
+ @ops.input_position(processor="bottom")
94
+ @op("Chat processor")
95
+ def chat_processor(processor, *, _ctx: one_by_one.Context):
96
+ cfg = _ctx.last_result or {'question_processors': [], 'answer_processors': [], 'masks': []}
97
+ for f in ['question_processor', 'answer_processor', 'mask']:
98
+ if f in processor:
99
+ cfg[f + 's'].append(processor[f])
100
+ question_processors = cfg['question_processors'][:]
101
+ answer_processors = cfg['answer_processors'][:]
102
+ masking_templates = {}
103
+ for mask in cfg['masks']:
104
+ masking_templates[mask['name']] = mask
105
+ if masking_templates:
106
+ question_processors.append(MaskTemplate(masking_templates=masking_templates))
107
+ answer_processors.append(MaskTemplate(masking_templates=masking_templates))
108
+ chat_processor = ChatProcessor(question_processors=question_processors, answer_processors=answer_processors)
109
+ return {'chat_processor': chat_processor, **cfg}
110
+
111
+ @output_on_top
112
+ @op("Truncate history")
113
+ def truncate_history(*, max_tokens=10000, language='English'):
114
+ return {'question_processor': TruncateHistory(max_tokens=max_tokens, language=language.lower())}
115
+
116
+ @output_on_top
117
+ @op("Mask")
118
+ def mask(*, name='', regex='', exceptions='', mask_pattern=''):
119
+ exceptions = [e.strip() for e in exceptions.split(',') if e.strip()]
120
+ return {'mask': {'name': name, 'regex': regex, 'exceptions': exceptions, 'mask_pattern': mask_pattern}}
121
+
122
+ @ops.input_position(chat_api="bottom")
123
+ @op("Test Chat API")
124
+ def test_chat_api(message, chat_api, *, show_details=False):
125
+ chat_api = chat_api[0]['chat_api']
126
+ request = ChatAPIRequest(session_id="b43215a0-428f-11ef-9454-0242ac120002", question=message['text'], history=[])
127
+ response = asyncio.run(chat_api.answer(request))
128
+ if show_details:
129
+ return {**response.__dict__}
130
+ else:
131
+ return {'answer': response.answer}
132
+
133
+ @op("Input chat")
134
+ def input_chat(*, chat: str):
135
+ return {'text': chat}
136
+
137
+ @output_on_top
138
+ @ops.input_position(chatbot="bottom", chat_processor="bottom", knowledge_base="bottom")
139
+ @op("Chat API")
140
+ def chat_api(chatbot, chat_processor, knowledge_base, *, model='gpt-4o-mini'):
141
+ chatbot = chatbot[0]['chatbot']
142
+ chat_processor = chat_processor[0]['chat_processor']
143
+ knowledge_base = knowledge_base[0]
144
+ c = ChatAPI(
145
+ chatbot=chatbot,
146
+ chat_processor=chat_processor,
147
+ model=model,
148
+ )
149
+ if knowledge_base:
150
+ c.chatbot.rag_graph.kg_base.load_v1_knowledge_base(**knowledge_base)
151
+ c.chatbot.scenario_selector.check_compatibility(c.chatbot.rag_graph)
152
+ return {'chat_api': c}
153
+
154
+ @output_on_top
155
+ @op("Knowledge base")
156
+ def knowledge_base(*, nodes_path='nodes.pickle', edges_path='edges.pickle', template_cluster_path='tempclusters.pickle'):
157
+ return {'nodes_path': nodes_path, 'edges_path': edges_path, 'template_cluster_path': template_cluster_path}
158
+
159
+ @op("View", view="table_view")
160
+ def view(input):
161
+ columns = [str(c) for c in input.keys() if not str(c).startswith('_')]
162
+ v = {
163
+ 'dataframes': { 'df': {
164
+ 'columns': columns,
165
+ 'data': [[input[c] for c in columns]],
166
+ }}
167
+ }
168
+ return v
169
+
170
+ async def api_service(request):
171
+ '''
172
+ Serves a chat endpoint that matches LynxScribe's interface.
173
+ To access it you need to add the "module" and "workspace"
174
+ parameters.
175
+ The workspace must contain exactly one "Chat API" node.
176
+
177
+ curl -X POST ${LYNXKITE_URL}/api/service \
178
+ -H "Content-Type: application/json" \
179
+ -d '{
180
+ "module": "server.lynxscribe_ops",
181
+ "workspace": "LynxScribe demo",
182
+ "session_id": "b43215a0-428f-11ef-9454-0242ac120002",
183
+ "question": "what does the fox say",
184
+ "history": [],
185
+ "user_id": "x",
186
+ "meta_inputs": {}
187
+ }'
188
+ '''
189
+ import pathlib
190
+ from . import workspace
191
+ DATA_PATH = pathlib.Path.cwd() / 'data'
192
+ path = DATA_PATH / request['workspace']
193
+ assert path.is_relative_to(DATA_PATH)
194
+ assert path.exists(), f'Workspace {path} does not exist'
195
+ ws = workspace.load(path)
196
+ contexts = ops.EXECUTORS[ENV](ws)
197
+ nodes = [op for op in ws.nodes if op.data.title == 'Chat API']
198
+ [node] = nodes
199
+ context = contexts[node.id]
200
+ chat_api = context.last_result['chat_api']
201
+ request = ChatAPIRequest(session_id=request['session_id'], question=request['question'], history=request['history'])
202
+ response = await chat_api.answer(request)
203
+ return response
server/main.py CHANGED
@@ -1,5 +1,6 @@
1
  import dataclasses
2
  import fastapi
 
3
  import pathlib
4
  import pkgutil
5
  from . import crdt
@@ -7,10 +8,12 @@ from . import ops
7
  from . import workspace
8
 
9
  here = pathlib.Path(__file__).parent
 
10
  for _, name, _ in pkgutil.iter_modules([str(here)]):
11
  if name.endswith('_ops') and not name.startswith('test_'):
12
  print(f'Importing {name}')
13
- __import__(f'server.{name}')
 
14
 
15
  app = fastapi.FastAPI(lifespan=crdt.lifespan)
16
  app.include_router(crdt.router)
@@ -68,3 +71,9 @@ def make_dir(req: dict):
68
  assert not path.exists()
69
  path.mkdir()
70
  return list_dir(path.parent)
 
 
 
 
 
 
 
1
  import dataclasses
2
  import fastapi
3
+ import importlib
4
  import pathlib
5
  import pkgutil
6
  from . import crdt
 
8
  from . import workspace
9
 
10
  here = pathlib.Path(__file__).parent
11
+ lynxkite_modules = {}
12
  for _, name, _ in pkgutil.iter_modules([str(here)]):
13
  if name.endswith('_ops') and not name.startswith('test_'):
14
  print(f'Importing {name}')
15
+ name = f'server.{name}'
16
+ lynxkite_modules[name] = importlib.import_module(name)
17
 
18
  app = fastapi.FastAPI(lifespan=crdt.lifespan)
19
  app.include_router(crdt.router)
 
71
  assert not path.exists()
72
  path.mkdir()
73
  return list_dir(path.parent)
74
+
75
+ @app.post("/api/service")
76
+ async def service(req: dict):
77
+ '''Executors can provide extra HTTP APIs through the /api/service endpoint.'''
78
+ module = lynxkite_modules[req['module']]
79
+ return await module.api_service(req)
server/ops.py CHANGED
@@ -61,7 +61,7 @@ class Parameter(BaseConfig):
61
  if default is inspect._empty:
62
  default = None
63
  if type is None or type is inspect._empty:
64
- type = typeof(default) if default else None
65
  return Parameter(name=name, default=default, type=type)
66
 
67
  class Input(BaseConfig):
 
61
  if default is inspect._empty:
62
  default = None
63
  if type is None or type is inspect._empty:
64
+ type = typeof(default) if default is not None else None
65
  return Parameter(name=name, default=default, type=type)
66
 
67
  class Input(BaseConfig):
web/package-lock.json CHANGED
@@ -25,6 +25,7 @@
25
  "sass": "1.79.5",
26
  "svelte": "4.2.19",
27
  "svelte-check": "4.0.5",
 
28
  "tslib": "2.7.0",
29
  "typescript": "5.6.3",
30
  "unplugin-icons": "0.19.3",
@@ -66,70 +67,6 @@
66
  "url": "https://github.com/sponsors/antfu"
67
  }
68
  },
69
- "node_modules/@esbuild/aix-ppc64": {
70
- "version": "0.21.5",
71
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
72
- "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
73
- "cpu": [
74
- "ppc64"
75
- ],
76
- "dev": true,
77
- "optional": true,
78
- "os": [
79
- "aix"
80
- ],
81
- "engines": {
82
- "node": ">=12"
83
- }
84
- },
85
- "node_modules/@esbuild/android-arm": {
86
- "version": "0.21.5",
87
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
88
- "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
89
- "cpu": [
90
- "arm"
91
- ],
92
- "dev": true,
93
- "optional": true,
94
- "os": [
95
- "android"
96
- ],
97
- "engines": {
98
- "node": ">=12"
99
- }
100
- },
101
- "node_modules/@esbuild/android-arm64": {
102
- "version": "0.21.5",
103
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
104
- "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
105
- "cpu": [
106
- "arm64"
107
- ],
108
- "dev": true,
109
- "optional": true,
110
- "os": [
111
- "android"
112
- ],
113
- "engines": {
114
- "node": ">=12"
115
- }
116
- },
117
- "node_modules/@esbuild/android-x64": {
118
- "version": "0.21.5",
119
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
120
- "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
121
- "cpu": [
122
- "x64"
123
- ],
124
- "dev": true,
125
- "optional": true,
126
- "os": [
127
- "android"
128
- ],
129
- "engines": {
130
- "node": ">=12"
131
- }
132
- },
133
  "node_modules/@esbuild/darwin-arm64": {
134
  "version": "0.21.5",
135
  "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
@@ -146,294 +83,6 @@
146
  "node": ">=12"
147
  }
148
  },
149
- "node_modules/@esbuild/darwin-x64": {
150
- "version": "0.21.5",
151
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
152
- "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
153
- "cpu": [
154
- "x64"
155
- ],
156
- "dev": true,
157
- "optional": true,
158
- "os": [
159
- "darwin"
160
- ],
161
- "engines": {
162
- "node": ">=12"
163
- }
164
- },
165
- "node_modules/@esbuild/freebsd-arm64": {
166
- "version": "0.21.5",
167
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
168
- "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
169
- "cpu": [
170
- "arm64"
171
- ],
172
- "dev": true,
173
- "optional": true,
174
- "os": [
175
- "freebsd"
176
- ],
177
- "engines": {
178
- "node": ">=12"
179
- }
180
- },
181
- "node_modules/@esbuild/freebsd-x64": {
182
- "version": "0.21.5",
183
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
184
- "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
185
- "cpu": [
186
- "x64"
187
- ],
188
- "dev": true,
189
- "optional": true,
190
- "os": [
191
- "freebsd"
192
- ],
193
- "engines": {
194
- "node": ">=12"
195
- }
196
- },
197
- "node_modules/@esbuild/linux-arm": {
198
- "version": "0.21.5",
199
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
200
- "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
201
- "cpu": [
202
- "arm"
203
- ],
204
- "dev": true,
205
- "optional": true,
206
- "os": [
207
- "linux"
208
- ],
209
- "engines": {
210
- "node": ">=12"
211
- }
212
- },
213
- "node_modules/@esbuild/linux-arm64": {
214
- "version": "0.21.5",
215
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
216
- "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
217
- "cpu": [
218
- "arm64"
219
- ],
220
- "dev": true,
221
- "optional": true,
222
- "os": [
223
- "linux"
224
- ],
225
- "engines": {
226
- "node": ">=12"
227
- }
228
- },
229
- "node_modules/@esbuild/linux-ia32": {
230
- "version": "0.21.5",
231
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
232
- "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
233
- "cpu": [
234
- "ia32"
235
- ],
236
- "dev": true,
237
- "optional": true,
238
- "os": [
239
- "linux"
240
- ],
241
- "engines": {
242
- "node": ">=12"
243
- }
244
- },
245
- "node_modules/@esbuild/linux-loong64": {
246
- "version": "0.21.5",
247
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
248
- "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
249
- "cpu": [
250
- "loong64"
251
- ],
252
- "dev": true,
253
- "optional": true,
254
- "os": [
255
- "linux"
256
- ],
257
- "engines": {
258
- "node": ">=12"
259
- }
260
- },
261
- "node_modules/@esbuild/linux-mips64el": {
262
- "version": "0.21.5",
263
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
264
- "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
265
- "cpu": [
266
- "mips64el"
267
- ],
268
- "dev": true,
269
- "optional": true,
270
- "os": [
271
- "linux"
272
- ],
273
- "engines": {
274
- "node": ">=12"
275
- }
276
- },
277
- "node_modules/@esbuild/linux-ppc64": {
278
- "version": "0.21.5",
279
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
280
- "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
281
- "cpu": [
282
- "ppc64"
283
- ],
284
- "dev": true,
285
- "optional": true,
286
- "os": [
287
- "linux"
288
- ],
289
- "engines": {
290
- "node": ">=12"
291
- }
292
- },
293
- "node_modules/@esbuild/linux-riscv64": {
294
- "version": "0.21.5",
295
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
296
- "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
297
- "cpu": [
298
- "riscv64"
299
- ],
300
- "dev": true,
301
- "optional": true,
302
- "os": [
303
- "linux"
304
- ],
305
- "engines": {
306
- "node": ">=12"
307
- }
308
- },
309
- "node_modules/@esbuild/linux-s390x": {
310
- "version": "0.21.5",
311
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
312
- "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
313
- "cpu": [
314
- "s390x"
315
- ],
316
- "dev": true,
317
- "optional": true,
318
- "os": [
319
- "linux"
320
- ],
321
- "engines": {
322
- "node": ">=12"
323
- }
324
- },
325
- "node_modules/@esbuild/linux-x64": {
326
- "version": "0.21.5",
327
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
328
- "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
329
- "cpu": [
330
- "x64"
331
- ],
332
- "dev": true,
333
- "optional": true,
334
- "os": [
335
- "linux"
336
- ],
337
- "engines": {
338
- "node": ">=12"
339
- }
340
- },
341
- "node_modules/@esbuild/netbsd-x64": {
342
- "version": "0.21.5",
343
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
344
- "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
345
- "cpu": [
346
- "x64"
347
- ],
348
- "dev": true,
349
- "optional": true,
350
- "os": [
351
- "netbsd"
352
- ],
353
- "engines": {
354
- "node": ">=12"
355
- }
356
- },
357
- "node_modules/@esbuild/openbsd-x64": {
358
- "version": "0.21.5",
359
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
360
- "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
361
- "cpu": [
362
- "x64"
363
- ],
364
- "dev": true,
365
- "optional": true,
366
- "os": [
367
- "openbsd"
368
- ],
369
- "engines": {
370
- "node": ">=12"
371
- }
372
- },
373
- "node_modules/@esbuild/sunos-x64": {
374
- "version": "0.21.5",
375
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
376
- "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
377
- "cpu": [
378
- "x64"
379
- ],
380
- "dev": true,
381
- "optional": true,
382
- "os": [
383
- "sunos"
384
- ],
385
- "engines": {
386
- "node": ">=12"
387
- }
388
- },
389
- "node_modules/@esbuild/win32-arm64": {
390
- "version": "0.21.5",
391
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
392
- "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
393
- "cpu": [
394
- "arm64"
395
- ],
396
- "dev": true,
397
- "optional": true,
398
- "os": [
399
- "win32"
400
- ],
401
- "engines": {
402
- "node": ">=12"
403
- }
404
- },
405
- "node_modules/@esbuild/win32-ia32": {
406
- "version": "0.21.5",
407
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
408
- "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
409
- "cpu": [
410
- "ia32"
411
- ],
412
- "dev": true,
413
- "optional": true,
414
- "os": [
415
- "win32"
416
- ],
417
- "engines": {
418
- "node": ">=12"
419
- }
420
- },
421
- "node_modules/@esbuild/win32-x64": {
422
- "version": "0.21.5",
423
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
424
- "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
425
- "cpu": [
426
- "x64"
427
- ],
428
- "dev": true,
429
- "optional": true,
430
- "os": [
431
- "win32"
432
- ],
433
- "engines": {
434
- "node": ">=12"
435
- }
436
- },
437
  "node_modules/@iconify-json/tabler": {
438
  "version": "1.2.5",
439
  "resolved": "https://registry.npmjs.org/@iconify-json/tabler/-/tabler-1.2.5.tgz",
@@ -468,307 +117,87 @@
468
  "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
469
  "dependencies": {
470
  "@jridgewell/set-array": "^1.2.1",
471
- "@jridgewell/sourcemap-codec": "^1.4.10",
472
- "@jridgewell/trace-mapping": "^0.3.24"
473
- },
474
- "engines": {
475
- "node": ">=6.0.0"
476
- }
477
- },
478
- "node_modules/@jridgewell/resolve-uri": {
479
- "version": "3.1.2",
480
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
481
- "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
482
- "engines": {
483
- "node": ">=6.0.0"
484
- }
485
- },
486
- "node_modules/@jridgewell/set-array": {
487
- "version": "1.2.1",
488
- "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
489
- "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
490
- "engines": {
491
- "node": ">=6.0.0"
492
- }
493
- },
494
- "node_modules/@jridgewell/sourcemap-codec": {
495
- "version": "1.5.0",
496
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
497
- "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="
498
- },
499
- "node_modules/@jridgewell/trace-mapping": {
500
- "version": "0.3.25",
501
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
502
- "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
503
- "dependencies": {
504
- "@jridgewell/resolve-uri": "^3.1.0",
505
- "@jridgewell/sourcemap-codec": "^1.4.14"
506
- }
507
- },
508
- "node_modules/@parcel/watcher": {
509
- "version": "2.4.1",
510
- "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.4.1.tgz",
511
- "integrity": "sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==",
512
- "dev": true,
513
- "dependencies": {
514
- "detect-libc": "^1.0.3",
515
- "is-glob": "^4.0.3",
516
- "micromatch": "^4.0.5",
517
- "node-addon-api": "^7.0.0"
518
- },
519
- "engines": {
520
- "node": ">= 10.0.0"
521
- },
522
- "funding": {
523
- "type": "opencollective",
524
- "url": "https://opencollective.com/parcel"
525
- },
526
- "optionalDependencies": {
527
- "@parcel/watcher-android-arm64": "2.4.1",
528
- "@parcel/watcher-darwin-arm64": "2.4.1",
529
- "@parcel/watcher-darwin-x64": "2.4.1",
530
- "@parcel/watcher-freebsd-x64": "2.4.1",
531
- "@parcel/watcher-linux-arm-glibc": "2.4.1",
532
- "@parcel/watcher-linux-arm64-glibc": "2.4.1",
533
- "@parcel/watcher-linux-arm64-musl": "2.4.1",
534
- "@parcel/watcher-linux-x64-glibc": "2.4.1",
535
- "@parcel/watcher-linux-x64-musl": "2.4.1",
536
- "@parcel/watcher-win32-arm64": "2.4.1",
537
- "@parcel/watcher-win32-ia32": "2.4.1",
538
- "@parcel/watcher-win32-x64": "2.4.1"
539
- }
540
- },
541
- "node_modules/@parcel/watcher-android-arm64": {
542
- "version": "2.4.1",
543
- "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.4.1.tgz",
544
- "integrity": "sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==",
545
- "cpu": [
546
- "arm64"
547
- ],
548
- "dev": true,
549
- "optional": true,
550
- "os": [
551
- "android"
552
- ],
553
- "engines": {
554
- "node": ">= 10.0.0"
555
- },
556
- "funding": {
557
- "type": "opencollective",
558
- "url": "https://opencollective.com/parcel"
559
- }
560
- },
561
- "node_modules/@parcel/watcher-darwin-arm64": {
562
- "version": "2.4.1",
563
- "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.4.1.tgz",
564
- "integrity": "sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==",
565
- "cpu": [
566
- "arm64"
567
- ],
568
- "dev": true,
569
- "optional": true,
570
- "os": [
571
- "darwin"
572
- ],
573
- "engines": {
574
- "node": ">= 10.0.0"
575
- },
576
- "funding": {
577
- "type": "opencollective",
578
- "url": "https://opencollective.com/parcel"
579
- }
580
- },
581
- "node_modules/@parcel/watcher-darwin-x64": {
582
- "version": "2.4.1",
583
- "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.4.1.tgz",
584
- "integrity": "sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==",
585
- "cpu": [
586
- "x64"
587
- ],
588
- "dev": true,
589
- "optional": true,
590
- "os": [
591
- "darwin"
592
- ],
593
- "engines": {
594
- "node": ">= 10.0.0"
595
- },
596
- "funding": {
597
- "type": "opencollective",
598
- "url": "https://opencollective.com/parcel"
599
- }
600
- },
601
- "node_modules/@parcel/watcher-freebsd-x64": {
602
- "version": "2.4.1",
603
- "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.4.1.tgz",
604
- "integrity": "sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==",
605
- "cpu": [
606
- "x64"
607
- ],
608
- "dev": true,
609
- "optional": true,
610
- "os": [
611
- "freebsd"
612
- ],
613
- "engines": {
614
- "node": ">= 10.0.0"
615
- },
616
- "funding": {
617
- "type": "opencollective",
618
- "url": "https://opencollective.com/parcel"
619
- }
620
- },
621
- "node_modules/@parcel/watcher-linux-arm-glibc": {
622
- "version": "2.4.1",
623
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.4.1.tgz",
624
- "integrity": "sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==",
625
- "cpu": [
626
- "arm"
627
- ],
628
- "dev": true,
629
- "optional": true,
630
- "os": [
631
- "linux"
632
- ],
633
- "engines": {
634
- "node": ">= 10.0.0"
635
- },
636
- "funding": {
637
- "type": "opencollective",
638
- "url": "https://opencollective.com/parcel"
639
- }
640
- },
641
- "node_modules/@parcel/watcher-linux-arm64-glibc": {
642
- "version": "2.4.1",
643
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.4.1.tgz",
644
- "integrity": "sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==",
645
- "cpu": [
646
- "arm64"
647
- ],
648
- "dev": true,
649
- "optional": true,
650
- "os": [
651
- "linux"
652
- ],
653
- "engines": {
654
- "node": ">= 10.0.0"
655
  },
656
- "funding": {
657
- "type": "opencollective",
658
- "url": "https://opencollective.com/parcel"
659
- }
660
- },
661
- "node_modules/@parcel/watcher-linux-arm64-musl": {
662
- "version": "2.4.1",
663
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.4.1.tgz",
664
- "integrity": "sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==",
665
- "cpu": [
666
- "arm64"
667
- ],
668
- "dev": true,
669
- "optional": true,
670
- "os": [
671
- "linux"
672
- ],
673
  "engines": {
674
- "node": ">= 10.0.0"
675
- },
676
- "funding": {
677
- "type": "opencollective",
678
- "url": "https://opencollective.com/parcel"
679
  }
680
  },
681
- "node_modules/@parcel/watcher-linux-x64-glibc": {
682
- "version": "2.4.1",
683
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.4.1.tgz",
684
- "integrity": "sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==",
685
- "cpu": [
686
- "x64"
687
- ],
688
- "dev": true,
689
- "optional": true,
690
- "os": [
691
- "linux"
692
- ],
693
  "engines": {
694
- "node": ">= 10.0.0"
695
- },
696
- "funding": {
697
- "type": "opencollective",
698
- "url": "https://opencollective.com/parcel"
699
  }
700
  },
701
- "node_modules/@parcel/watcher-linux-x64-musl": {
702
- "version": "2.4.1",
703
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.4.1.tgz",
704
- "integrity": "sha512-L2nZTYR1myLNST0O632g0Dx9LyMNHrn6TOt76sYxWLdff3cB22/GZX2UPtJnaqQPdCRoszoY5rcOj4oMTtp5fQ==",
705
- "cpu": [
706
- "x64"
707
- ],
708
- "dev": true,
709
- "optional": true,
710
- "os": [
711
- "linux"
712
- ],
713
  "engines": {
714
- "node": ">= 10.0.0"
715
- },
716
- "funding": {
717
- "type": "opencollective",
718
- "url": "https://opencollective.com/parcel"
719
  }
720
  },
721
- "node_modules/@parcel/watcher-win32-arm64": {
722
- "version": "2.4.1",
723
- "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.4.1.tgz",
724
- "integrity": "sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==",
725
- "cpu": [
726
- "arm64"
727
- ],
728
- "dev": true,
729
- "optional": true,
730
- "os": [
731
- "win32"
732
- ],
733
- "engines": {
734
- "node": ">= 10.0.0"
735
- },
736
- "funding": {
737
- "type": "opencollective",
738
- "url": "https://opencollective.com/parcel"
739
  }
740
  },
741
- "node_modules/@parcel/watcher-win32-ia32": {
742
  "version": "2.4.1",
743
- "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.4.1.tgz",
744
- "integrity": "sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==",
745
- "cpu": [
746
- "ia32"
747
- ],
748
  "dev": true,
749
- "optional": true,
750
- "os": [
751
- "win32"
752
- ],
 
 
753
  "engines": {
754
  "node": ">= 10.0.0"
755
  },
756
  "funding": {
757
  "type": "opencollective",
758
  "url": "https://opencollective.com/parcel"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
759
  }
760
  },
761
- "node_modules/@parcel/watcher-win32-x64": {
762
  "version": "2.4.1",
763
- "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.4.1.tgz",
764
- "integrity": "sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==",
765
  "cpu": [
766
- "x64"
767
  ],
768
  "dev": true,
769
  "optional": true,
770
  "os": [
771
- "win32"
772
  ],
773
  "engines": {
774
  "node": ">= 10.0.0"
@@ -793,32 +222,6 @@
793
  "integrity": "sha512-KnINM/Sng25QAv6sHkJO9q/XyslLegCF5jTsTSVu+AouY3uZDVf4Am99xNCqsfqFZFvnTBBDvCsHNdvTVGvPEA==",
794
  "dev": true
795
  },
796
- "node_modules/@rollup/rollup-android-arm-eabi": {
797
- "version": "4.24.0",
798
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz",
799
- "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==",
800
- "cpu": [
801
- "arm"
802
- ],
803
- "dev": true,
804
- "optional": true,
805
- "os": [
806
- "android"
807
- ]
808
- },
809
- "node_modules/@rollup/rollup-android-arm64": {
810
- "version": "4.24.0",
811
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz",
812
- "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==",
813
- "cpu": [
814
- "arm64"
815
- ],
816
- "dev": true,
817
- "optional": true,
818
- "os": [
819
- "android"
820
- ]
821
- },
822
  "node_modules/@rollup/rollup-darwin-arm64": {
823
  "version": "4.24.0",
824
  "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz",
@@ -832,175 +235,6 @@
832
  "darwin"
833
  ]
834
  },
835
- "node_modules/@rollup/rollup-darwin-x64": {
836
- "version": "4.24.0",
837
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz",
838
- "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==",
839
- "cpu": [
840
- "x64"
841
- ],
842
- "dev": true,
843
- "optional": true,
844
- "os": [
845
- "darwin"
846
- ]
847
- },
848
- "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
849
- "version": "4.24.0",
850
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz",
851
- "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==",
852
- "cpu": [
853
- "arm"
854
- ],
855
- "dev": true,
856
- "optional": true,
857
- "os": [
858
- "linux"
859
- ]
860
- },
861
- "node_modules/@rollup/rollup-linux-arm-musleabihf": {
862
- "version": "4.24.0",
863
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz",
864
- "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==",
865
- "cpu": [
866
- "arm"
867
- ],
868
- "dev": true,
869
- "optional": true,
870
- "os": [
871
- "linux"
872
- ]
873
- },
874
- "node_modules/@rollup/rollup-linux-arm64-gnu": {
875
- "version": "4.24.0",
876
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz",
877
- "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==",
878
- "cpu": [
879
- "arm64"
880
- ],
881
- "dev": true,
882
- "optional": true,
883
- "os": [
884
- "linux"
885
- ]
886
- },
887
- "node_modules/@rollup/rollup-linux-arm64-musl": {
888
- "version": "4.24.0",
889
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz",
890
- "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==",
891
- "cpu": [
892
- "arm64"
893
- ],
894
- "dev": true,
895
- "optional": true,
896
- "os": [
897
- "linux"
898
- ]
899
- },
900
- "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
901
- "version": "4.24.0",
902
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz",
903
- "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==",
904
- "cpu": [
905
- "ppc64"
906
- ],
907
- "dev": true,
908
- "optional": true,
909
- "os": [
910
- "linux"
911
- ]
912
- },
913
- "node_modules/@rollup/rollup-linux-riscv64-gnu": {
914
- "version": "4.24.0",
915
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz",
916
- "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==",
917
- "cpu": [
918
- "riscv64"
919
- ],
920
- "dev": true,
921
- "optional": true,
922
- "os": [
923
- "linux"
924
- ]
925
- },
926
- "node_modules/@rollup/rollup-linux-s390x-gnu": {
927
- "version": "4.24.0",
928
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz",
929
- "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==",
930
- "cpu": [
931
- "s390x"
932
- ],
933
- "dev": true,
934
- "optional": true,
935
- "os": [
936
- "linux"
937
- ]
938
- },
939
- "node_modules/@rollup/rollup-linux-x64-gnu": {
940
- "version": "4.24.0",
941
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz",
942
- "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==",
943
- "cpu": [
944
- "x64"
945
- ],
946
- "dev": true,
947
- "optional": true,
948
- "os": [
949
- "linux"
950
- ]
951
- },
952
- "node_modules/@rollup/rollup-linux-x64-musl": {
953
- "version": "4.24.0",
954
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz",
955
- "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==",
956
- "cpu": [
957
- "x64"
958
- ],
959
- "dev": true,
960
- "optional": true,
961
- "os": [
962
- "linux"
963
- ]
964
- },
965
- "node_modules/@rollup/rollup-win32-arm64-msvc": {
966
- "version": "4.24.0",
967
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz",
968
- "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==",
969
- "cpu": [
970
- "arm64"
971
- ],
972
- "dev": true,
973
- "optional": true,
974
- "os": [
975
- "win32"
976
- ]
977
- },
978
- "node_modules/@rollup/rollup-win32-ia32-msvc": {
979
- "version": "4.24.0",
980
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz",
981
- "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==",
982
- "cpu": [
983
- "ia32"
984
- ],
985
- "dev": true,
986
- "optional": true,
987
- "os": [
988
- "win32"
989
- ]
990
- },
991
- "node_modules/@rollup/rollup-win32-x64-msvc": {
992
- "version": "4.24.0",
993
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz",
994
- "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==",
995
- "cpu": [
996
- "x64"
997
- ],
998
- "dev": true,
999
- "optional": true,
1000
- "os": [
1001
- "win32"
1002
- ]
1003
- },
1004
  "node_modules/@svelte-put/shortcut": {
1005
  "version": "3.1.1",
1006
  "resolved": "https://registry.npmjs.org/@svelte-put/shortcut/-/shortcut-3.1.1.tgz",
@@ -1148,6 +382,12 @@
1148
  "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
1149
  "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="
1150
  },
 
 
 
 
 
 
1151
  "node_modules/@xyflow/svelte": {
1152
  "version": "0.1.21",
1153
  "resolved": "https://registry.npmjs.org/@xyflow/svelte/-/svelte-0.1.21.tgz",
@@ -1933,6 +1173,18 @@
1933
  "@jridgewell/sourcemap-codec": "^1.5.0"
1934
  }
1935
  },
 
 
 
 
 
 
 
 
 
 
 
 
1936
  "node_modules/mdn-data": {
1937
  "version": "2.0.30",
1938
  "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
@@ -2335,6 +1587,19 @@
2335
  "svelte": "^3.19.0 || ^4.0.0"
2336
  }
2337
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
2338
  "node_modules/tinyexec": {
2339
  "version": "0.3.0",
2340
  "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.0.tgz",
 
25
  "sass": "1.79.5",
26
  "svelte": "4.2.19",
27
  "svelte-check": "4.0.5",
28
+ "svelte-markdown": "^0.4.1",
29
  "tslib": "2.7.0",
30
  "typescript": "5.6.3",
31
  "unplugin-icons": "0.19.3",
 
67
  "url": "https://github.com/sponsors/antfu"
68
  }
69
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  "node_modules/@esbuild/darwin-arm64": {
71
  "version": "0.21.5",
72
  "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
 
83
  "node": ">=12"
84
  }
85
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  "node_modules/@iconify-json/tabler": {
87
  "version": "1.2.5",
88
  "resolved": "https://registry.npmjs.org/@iconify-json/tabler/-/tabler-1.2.5.tgz",
 
117
  "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
118
  "dependencies": {
119
  "@jridgewell/set-array": "^1.2.1",
120
+ "@jridgewell/sourcemap-codec": "^1.4.10",
121
+ "@jridgewell/trace-mapping": "^0.3.24"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  "engines": {
124
+ "node": ">=6.0.0"
 
 
 
 
125
  }
126
  },
127
+ "node_modules/@jridgewell/resolve-uri": {
128
+ "version": "3.1.2",
129
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
130
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
 
 
 
 
 
 
 
 
131
  "engines": {
132
+ "node": ">=6.0.0"
 
 
 
 
133
  }
134
  },
135
+ "node_modules/@jridgewell/set-array": {
136
+ "version": "1.2.1",
137
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
138
+ "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
 
 
 
 
 
 
 
 
139
  "engines": {
140
+ "node": ">=6.0.0"
 
 
 
 
141
  }
142
  },
143
+ "node_modules/@jridgewell/sourcemap-codec": {
144
+ "version": "1.5.0",
145
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
146
+ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="
147
+ },
148
+ "node_modules/@jridgewell/trace-mapping": {
149
+ "version": "0.3.25",
150
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
151
+ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
152
+ "dependencies": {
153
+ "@jridgewell/resolve-uri": "^3.1.0",
154
+ "@jridgewell/sourcemap-codec": "^1.4.14"
 
 
 
 
 
 
155
  }
156
  },
157
+ "node_modules/@parcel/watcher": {
158
  "version": "2.4.1",
159
+ "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.4.1.tgz",
160
+ "integrity": "sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==",
 
 
 
161
  "dev": true,
162
+ "dependencies": {
163
+ "detect-libc": "^1.0.3",
164
+ "is-glob": "^4.0.3",
165
+ "micromatch": "^4.0.5",
166
+ "node-addon-api": "^7.0.0"
167
+ },
168
  "engines": {
169
  "node": ">= 10.0.0"
170
  },
171
  "funding": {
172
  "type": "opencollective",
173
  "url": "https://opencollective.com/parcel"
174
+ },
175
+ "optionalDependencies": {
176
+ "@parcel/watcher-android-arm64": "2.4.1",
177
+ "@parcel/watcher-darwin-arm64": "2.4.1",
178
+ "@parcel/watcher-darwin-x64": "2.4.1",
179
+ "@parcel/watcher-freebsd-x64": "2.4.1",
180
+ "@parcel/watcher-linux-arm-glibc": "2.4.1",
181
+ "@parcel/watcher-linux-arm64-glibc": "2.4.1",
182
+ "@parcel/watcher-linux-arm64-musl": "2.4.1",
183
+ "@parcel/watcher-linux-x64-glibc": "2.4.1",
184
+ "@parcel/watcher-linux-x64-musl": "2.4.1",
185
+ "@parcel/watcher-win32-arm64": "2.4.1",
186
+ "@parcel/watcher-win32-ia32": "2.4.1",
187
+ "@parcel/watcher-win32-x64": "2.4.1"
188
  }
189
  },
190
+ "node_modules/@parcel/watcher-darwin-arm64": {
191
  "version": "2.4.1",
192
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.4.1.tgz",
193
+ "integrity": "sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==",
194
  "cpu": [
195
+ "arm64"
196
  ],
197
  "dev": true,
198
  "optional": true,
199
  "os": [
200
+ "darwin"
201
  ],
202
  "engines": {
203
  "node": ">= 10.0.0"
 
222
  "integrity": "sha512-KnINM/Sng25QAv6sHkJO9q/XyslLegCF5jTsTSVu+AouY3uZDVf4Am99xNCqsfqFZFvnTBBDvCsHNdvTVGvPEA==",
223
  "dev": true
224
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
225
  "node_modules/@rollup/rollup-darwin-arm64": {
226
  "version": "4.24.0",
227
  "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz",
 
235
  "darwin"
236
  ]
237
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238
  "node_modules/@svelte-put/shortcut": {
239
  "version": "3.1.1",
240
  "resolved": "https://registry.npmjs.org/@svelte-put/shortcut/-/shortcut-3.1.1.tgz",
 
382
  "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
383
  "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="
384
  },
385
+ "node_modules/@types/marked": {
386
+ "version": "5.0.2",
387
+ "resolved": "https://registry.npmjs.org/@types/marked/-/marked-5.0.2.tgz",
388
+ "integrity": "sha512-OucS4KMHhFzhz27KxmWg7J+kIYqyqoW5kdIEI319hqARQQUTqhao3M/F+uFnDXD0Rg72iDDZxZNxq5gvctmLlg==",
389
+ "dev": true
390
+ },
391
  "node_modules/@xyflow/svelte": {
392
  "version": "0.1.21",
393
  "resolved": "https://registry.npmjs.org/@xyflow/svelte/-/svelte-0.1.21.tgz",
 
1173
  "@jridgewell/sourcemap-codec": "^1.5.0"
1174
  }
1175
  },
1176
+ "node_modules/marked": {
1177
+ "version": "5.1.2",
1178
+ "resolved": "https://registry.npmjs.org/marked/-/marked-5.1.2.tgz",
1179
+ "integrity": "sha512-ahRPGXJpjMjwSOlBoTMZAK7ATXkli5qCPxZ21TG44rx1KEo44bii4ekgTDQPNRQ4Kh7JMb9Ub1PVk1NxRSsorg==",
1180
+ "dev": true,
1181
+ "bin": {
1182
+ "marked": "bin/marked.js"
1183
+ },
1184
+ "engines": {
1185
+ "node": ">= 16"
1186
+ }
1187
+ },
1188
  "node_modules/mdn-data": {
1189
  "version": "2.0.30",
1190
  "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
 
1587
  "svelte": "^3.19.0 || ^4.0.0"
1588
  }
1589
  },
1590
+ "node_modules/svelte-markdown": {
1591
+ "version": "0.4.1",
1592
+ "resolved": "https://registry.npmjs.org/svelte-markdown/-/svelte-markdown-0.4.1.tgz",
1593
+ "integrity": "sha512-pOlLY6EruKJaWI9my/2bKX8PdTeP5CM0s4VMmwmC2prlOkjAf+AOmTM4wW/l19Y6WZ87YmP8+ZCJCCwBChWjYw==",
1594
+ "dev": true,
1595
+ "dependencies": {
1596
+ "@types/marked": "^5.0.1",
1597
+ "marked": "^5.1.2"
1598
+ },
1599
+ "peerDependencies": {
1600
+ "svelte": "^4.0.0"
1601
+ }
1602
+ },
1603
  "node_modules/tinyexec": {
1604
  "version": "0.3.0",
1605
  "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.0.tgz",
web/package.json CHANGED
@@ -17,6 +17,7 @@
17
  "sass": "1.79.5",
18
  "svelte": "4.2.19",
19
  "svelte-check": "4.0.5",
 
20
  "tslib": "2.7.0",
21
  "typescript": "5.6.3",
22
  "unplugin-icons": "0.19.3",
 
17
  "sass": "1.79.5",
18
  "svelte": "4.2.19",
19
  "svelte-check": "4.0.5",
20
+ "svelte-markdown": "^0.4.1",
21
  "tslib": "2.7.0",
22
  "typescript": "5.6.3",
23
  "unplugin-icons": "0.19.3",
web/src/NodeParameter.svelte CHANGED
@@ -3,21 +3,24 @@
3
  export let value;
4
  export let meta;
5
  export let onChange;
 
6
  </script>
7
 
8
  <label class="param">
9
- <span class="param-name">{name.replace(/_/g, ' ')}</span>
10
  {#if meta?.type?.format === 'collapsed'}
 
11
  <button class="collapsed-param form-control form-control-sm">
12
 
13
  </button>
14
  {:else if meta?.type?.format === 'textarea'}
 
15
  <textarea class="form-control form-control-sm"
16
- rows="6"
17
- value={value}
18
- on:change={(evt) => onChange(evt.currentTarget.value)}
19
- />
20
  {:else if meta?.type?.enum}
 
21
  <select class="form-select form-select-sm"
22
  value={value || meta.type.enum[0]}
23
  on:change={(evt) => onChange(evt.currentTarget.value)}
@@ -26,11 +29,21 @@
26
  <option value={option}>{option}</option>
27
  {/each}
28
  </select>
 
 
 
 
 
 
 
 
 
29
  {:else}
 
30
  <input class="form-control form-control-sm"
31
- value={value}
32
- on:change={(evt) => onChange(evt.currentTarget.value)}
33
- />
34
  {/if}
35
  </label>
36
 
 
3
  export let value;
4
  export let meta;
5
  export let onChange;
6
+ const BOOLEAN = "<class 'bool'>";
7
  </script>
8
 
9
  <label class="param">
 
10
  {#if meta?.type?.format === 'collapsed'}
11
+ <span class="param-name">{name.replace(/_/g, ' ')}</span>
12
  <button class="collapsed-param form-control form-control-sm">
13
 
14
  </button>
15
  {:else if meta?.type?.format === 'textarea'}
16
+ <span class="param-name">{name.replace(/_/g, ' ')}</span>
17
  <textarea class="form-control form-control-sm"
18
+ rows="6"
19
+ value={value}
20
+ on:change={(evt) => onChange(evt.currentTarget.value)}
21
+ />
22
  {:else if meta?.type?.enum}
23
+ <span class="param-name">{name.replace(/_/g, ' ')}</span>
24
  <select class="form-select form-select-sm"
25
  value={value || meta.type.enum[0]}
26
  on:change={(evt) => onChange(evt.currentTarget.value)}
 
29
  <option value={option}>{option}</option>
30
  {/each}
31
  </select>
32
+ {:else if meta?.type?.type === BOOLEAN}
33
+ <label class="form-check-label">
34
+ <input class="form-check-input"
35
+ type="checkbox"
36
+ checked={value}
37
+ on:change={(evt) => onChange(evt.currentTarget.checked)}
38
+ />
39
+ {name.replace(/_/g, ' ')}
40
+ </label>
41
  {:else}
42
+ <span class="param-name">{name.replace(/_/g, ' ')}</span>
43
  <input class="form-control form-control-sm"
44
+ value={value}
45
+ on:change={(evt) => onChange(evt.currentTarget.value)}
46
+ />
47
  {/if}
48
  </label>
49