darabos commited on
Commit
dfe2d8f
·
1 Parent(s): 70c66a8

Replace default_display with an input_metadata field with simpler semantics.

Browse files
examples/Model use CHANGED
@@ -42,31 +42,22 @@
42
  "data": {
43
  "__execution_delay": 0.0,
44
  "collapsed": null,
45
- "display": {
46
- "dataframes": {
47
- "df": {
48
- "columns": [
49
- "x",
50
- "y"
51
- ]
52
- },
53
- "df_test": {
54
- "columns": [
55
- "x",
56
- "y"
57
- ]
58
- },
59
- "df_train": {
60
- "columns": [
61
- "x",
62
- "y"
63
- ]
64
- }
65
- },
66
- "other": {},
67
- "relations": []
68
- },
69
  "error": null,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  "meta": {
71
  "inputs": {
72
  "bundle": {
@@ -128,6 +119,7 @@
128
  "collapsed": null,
129
  "display": null,
130
  "error": null,
 
131
  "meta": {
132
  "inputs": {},
133
  "name": "Import Parquet",
@@ -587,54 +579,54 @@
587
  ],
588
  "data": [
589
  [
590
- "[0.4827103 0.10563457 0.98858833 0.82286644]",
591
- "[1.48271036 1.10563457 1.98858833 1.82286644]",
592
- "[1.4503304958343506, 1.1575173139572144, 1.996051549911499, 1.8715994358062744]"
593
  ],
594
  [
595
- "[0.54914117 0.03810108 0.87531954 0.73044223]",
596
- "[1.54914117 1.03810108 1.87531948 1.73044229]",
597
- "[1.5054945945739746, 1.0799291133880615, 1.8784711360931396, 1.7745399475097656]"
598
  ],
599
  [
600
- "[0.26661873 0.45946234 0.13510543 0.81294441]",
601
- "[1.26661873 1.4594624 1.13510537 1.81294441]",
602
- "[1.2893636226654053, 1.4012629985809326, 1.1273266077041626, 1.7483277320861816]"
603
  ],
604
  [
605
- "[0.9630242 0.76359051 0.24853623 0.76881069]",
606
- "[1.96302414 1.76359057 1.24853623 1.76881075]",
607
- "[1.9627504348754883, 1.808237075805664, 1.2652870416641235, 1.7989287376403809]"
608
  ],
609
  [
610
- "[0.52046251 0.45887971 0.72169858 0.29517919]",
611
- "[1.52046251 1.45887971 1.72169852 1.29517913]",
612
- "[1.4980013370513916, 1.4540209770202637, 1.7123804092407227, 1.3061636686325073]"
613
  ],
614
  [
615
- "[0.62569475 0.9881897 0.83639616 0.9828859 ]",
616
- "[1.62569475 1.9881897 1.83639622 1.98288584]",
617
- "[1.6632444858551025, 2.0650277137756348, 1.8643897771835327, 2.032055377960205]"
618
  ],
619
  [
620
- "[0.95928186 0.84273899 0.71514636 0.38619852]",
621
- "[1.95928192 1.84273899 1.7151463 1.38619852]",
622
- "[1.943433403968811, 1.905775785446167, 1.727120280265808, 1.4508745670318604]"
623
  ],
624
  [
625
- "[0.94516498 0.08422136 0.5608117 0.07652664]",
626
- "[1.94516492 1.08422136 1.56081176 1.07652664]",
627
- "[1.8603894710540771, 1.0990982055664062, 1.5473597049713135, 1.1221177577972412]"
628
  ],
629
  [
630
- "[0.32225502 0.16999388 0.05823922 0.9628762 ]",
631
- "[1.32225502 1.16999388 1.05823922 1.9628762 ]",
632
- "[1.3253933191299438, 1.1194703578948975, 1.0517100095748901, 1.903820514678955]"
633
  ],
634
  [
635
- "[0.91730917 0.22574073 0.09591609 0.33056474]",
636
- "[1.91730917 1.22574067 1.09591603 1.33056474]",
637
- "[1.8627445697784424, 1.2110977172851562, 1.085142731666565, 1.3327856063842773]"
638
  ]
639
  ]
640
  },
@@ -644,6 +636,10 @@
644
  "y"
645
  ],
646
  "data": [
 
 
 
 
647
  [
648
  "[0.85706753 0.61447072 0.41741937 0.85147089]",
649
  "[1.85706758 1.61447072 1.41741943 1.85147095]"
@@ -676,6 +672,10 @@
676
  "[4.27091718e-01 4.89909172e-01 6.92297399e-01 2.57611275e-04]",
677
  "[1.42709172 1.48990917 1.69229746 1.00025761]"
678
  ],
 
 
 
 
679
  [
680
  "[0.50783676 0.04156506 0.21984279 0.8454656 ]",
681
  "[1.50783682 1.04156506 1.21984279 1.84546566]"
@@ -688,18 +688,10 @@
688
  "[0.11693293 0.49860179 0.55020827 0.88832849]",
689
  "[1.11693287 1.49860179 1.55020833 1.88832855]"
690
  ],
691
- [
692
- "[0.48959708 0.48549271 0.32688856 0.356677 ]",
693
- "[1.48959708 1.48549271 1.32688856 1.35667706]"
694
- ],
695
  [
696
  "[0.50272274 0.54912758 0.17663097 0.79070699]",
697
  "[1.50272274 1.54912758 1.17663097 1.79070699]"
698
  ],
699
- [
700
- "[0.04508126 0.76880038 0.80721325 0.62542385]",
701
- "[1.04508126 1.76880038 1.80721331 1.62542391]"
702
- ],
703
  [
704
  "[0.19908059 0.17570406 0.51475513 0.1893943 ]",
705
  "[1.19908059 1.175704 1.51475513 1.18939424]"
@@ -717,17 +709,13 @@
717
  "[1.24388778 1.07268476 1.68350863 1.73431659]"
718
  ],
719
  [
720
- "[0.56922203 0.98222166 0.76851749 0.28615737]",
721
- "[1.56922197 1.9822216 1.76851749 1.28615737]"
722
  ],
723
  [
724
  "[0.88776821 0.51636773 0.30333066 0.32230979]",
725
  "[1.88776827 1.51636767 1.30333066 1.32230973]"
726
  ],
727
- [
728
- "[0.90817457 0.89270043 0.38583666 0.66566533]",
729
- "[1.90817451 1.89270043 1.3858366 1.66566539]"
730
- ],
731
  [
732
  "[0.48507756 0.80808765 0.77162558 0.47834778]",
733
  "[1.48507762 1.80808759 1.77162552 1.47834778]"
@@ -752,6 +740,14 @@
752
  "[0.23942459 0.90487361 0.69337189 0.65089428]",
753
  "[1.23942459 1.90487361 1.69337189 1.65089428]"
754
  ],
 
 
 
 
 
 
 
 
755
  [
756
  "[0.30754459 0.77694583 0.09278506 0.38326019]",
757
  "[1.30754459 1.77694583 1.09278512 1.38326025]"
@@ -760,6 +756,10 @@
760
  "[0.27845025 0.32472342 0.82203609 0.77107543]",
761
  "[1.27845025 1.32472348 1.82203603 1.77107549]"
762
  ],
 
 
 
 
763
  [
764
  "[0.98033333 0.97656083 0.38939917 0.81491041]",
765
  "[1.98033333 1.97656083 1.38939917 1.81491041]"
@@ -816,10 +816,6 @@
816
  "[0.77427191 0.21829212 0.12769502 0.74303615]",
817
  "[1.77427197 1.21829212 1.12769508 1.74303615]"
818
  ],
819
- [
820
- "[0.08107251 0.2602725 0.18861133 0.44833237]",
821
- "[1.08107257 1.2602725 1.18861127 1.44833231]"
822
- ],
823
  [
824
  "[0.59812403 0.78395379 0.0291847 0.81814629]",
825
  "[1.59812403 1.78395379 1.0291847 1.81814623]"
@@ -840,6 +836,10 @@
840
  "[0.85566247 0.83362883 0.48424995 0.25265992]",
841
  "[1.85566247 1.83362889 1.48424995 1.25265992]"
842
  ],
 
 
 
 
843
  [
844
  "[0.32565445 0.90939188 0.07488042 0.13730896]",
845
  "[1.32565451 1.90939188 1.07488036 1.13730896]"
@@ -852,6 +852,10 @@
852
  "[0.79905868 0.89367443 0.75429088 0.3190186 ]",
853
  "[1.79905868 1.89367437 1.75429082 1.3190186 ]"
854
  ],
 
 
 
 
855
  [
856
  "[0.67418337 0.79634351 0.23229051 0.71345252]",
857
  "[1.67418337 1.79634356 1.23229051 1.71345258]"
@@ -896,6 +900,10 @@
896
  "[0.47963417 0.81818312 0.48720706 0.49339259]",
897
  "[1.47963417 1.81818318 1.48720706 1.49339259]"
898
  ],
 
 
 
 
899
  [
900
  "[0.60609657 0.96257663 0.19292736 0.95702219]",
901
  "[1.60609651 1.96257663 1.19292736 1.95702219]"
@@ -916,21 +924,13 @@
916
  "[0.59492421 0.90274489 0.38069052 0.46101224]",
917
  "[1.59492421 1.90274489 1.38069057 1.46101224]"
918
  ],
919
- [
920
- "[0.15064228 0.03198934 0.25754827 0.51484001]",
921
- "[1.15064228 1.03198934 1.25754833 1.51484001]"
922
- ],
923
  [
924
  "[0.12024075 0.21342516 0.56858408 0.58644271]",
925
  "[1.12024069 1.21342516 1.56858408 1.58644271]"
926
  ],
927
  [
928
- "[0.49691743 0.61873293 0.90698647 0.94486356]",
929
- "[1.49691749 1.61873293 1.90698647 1.94486356]"
930
- ],
931
- [
932
- "[0.6032477 0.83361369 0.18538666 0.19108021]",
933
- "[1.60324764 1.83361363 1.18538666 1.19108021]"
934
  ],
935
  [
936
  "[0.63235509 0.70352674 0.96188956 0.46240485]",
@@ -980,10 +980,6 @@
980
  "[0.28942841 0.05601001 0.33039129 0.27781558]",
981
  "[1.28942847 1.05601001 1.33039129 1.27781558]"
982
  ],
983
- [
984
- "[0.68094063 0.45189077 0.22661722 0.37354094]",
985
- "[1.68094063 1.45189071 1.22661722 1.37354088]"
986
- ],
987
  [
988
  "[0.43681622 0.74680805 0.83598751 0.12414402]",
989
  "[1.43681622 1.74680805 1.83598757 1.12414408]"
@@ -992,10 +988,6 @@
992
  "[0.47870928 0.17129105 0.27300501 0.20634609]",
993
  "[1.47870922 1.17129111 1.27300501 1.20634604]"
994
  ],
995
- [
996
- "[0.72795159 0.79317838 0.27832931 0.96576637]",
997
- "[1.72795153 1.79317832 1.27832937 1.96576643]"
998
- ],
999
  [
1000
  "[0.87608397 0.93200487 0.80169648 0.37758952]",
1001
  "[1.87608397 1.93200493 1.80169654 1.37758946]"
@@ -1008,11 +1000,55 @@
1008
  }
1009
  },
1010
  "other": {
1011
- "model": "ModelConfig(model=Sequential(\n (0) - Linear(in_features=4, out_features=4, bias=True): Input__embedding_1_x -> Linear_1_x\n (1) - <function leaky_relu at 0x731d1381bba0>: Linear_1_x -> Activation_2_x\n (2) - Identity(): Activation_2_x -> Activation_2_x\n), model_inputs=['Input__embedding_1_x'], model_outputs=['Activation_2_x'], loss_inputs=['Input__label_1_y', 'Activation_2_x'], loss=Sequential(\n (0) - <function mse_loss at 0x731d138216c0>: Activation_2_x, Input__label_1_y -> MSE_loss_1_loss\n (1) - Identity(): MSE_loss_1_loss -> loss\n), optimizer=SGD (\nParameter Group 0\n dampening: 0\n differentiable: False\n foreach: None\n fused: None\n lr: 0.1\n maximize: False\n momentum: 0\n nesterov: False\n weight_decay: 0\n), source_workspace=None, trained=True)"
1012
  },
1013
  "relations": []
1014
  },
1015
  "error": null,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1016
  "meta": {
1017
  "inputs": {
1018
  "bundle": {
@@ -1056,48 +1092,34 @@
1056
  "data": {
1057
  "__execution_delay": 0.0,
1058
  "collapsed": null,
1059
- "display": {
1060
- "dataframes": {
1061
- "df": {
1062
- "columns": [
1063
- "x",
1064
- "y"
1065
- ]
1066
- },
1067
- "df_test": {
1068
- "columns": [
1069
- "x",
1070
- "y"
1071
- ]
1072
- },
1073
- "df_train": {
1074
- "columns": [
1075
- "x",
1076
- "y"
1077
- ]
1078
- }
1079
- },
1080
- "other": {
1081
- "model": {
1082
- "model": {
1083
- "inputs": [
1084
- "Input__embedding_1_x"
1085
- ],
1086
- "loss_inputs": [
1087
- "Input__label_1_y",
1088
- "Activation_2_x"
1089
- ],
1090
- "outputs": [
1091
- "Activation_2_x"
1092
- ],
1093
- "trained": false
1094
- },
1095
- "type": "model"
1096
- }
1097
- },
1098
- "relations": []
1099
- },
1100
  "error": null,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1101
  "meta": {
1102
  "inputs": {
1103
  "bundle": {
@@ -1157,48 +1179,51 @@
1157
  "data": {
1158
  "__execution_delay": 0.0,
1159
  "collapsed": null,
1160
- "display": {
1161
- "dataframes": {
1162
- "df": {
1163
- "columns": [
1164
- "x",
1165
- "y"
1166
- ]
1167
- },
1168
- "df_test": {
1169
- "columns": [
1170
- "x",
1171
- "y"
1172
- ]
 
 
 
 
 
 
 
 
 
 
1173
  },
1174
- "df_train": {
1175
- "columns": [
1176
- "x",
1177
- "y"
1178
- ]
1179
- }
1180
- },
1181
- "other": {
1182
- "model": {
1183
  "model": {
1184
- "inputs": [
1185
- "Input__embedding_1_x"
1186
- ],
1187
- "loss_inputs": [
1188
- "Input__label_1_y",
1189
- "Activation_2_x"
1190
- ],
1191
- "outputs": [
1192
- "Activation_2_x"
1193
- ],
1194
- "trained": true
1195
- },
1196
- "type": "model"
1197
- }
1198
- },
1199
- "relations": []
1200
- },
1201
- "error": null,
 
1202
  "meta": {
1203
  "inputs": {
1204
  "bundle": {
@@ -1242,14 +1267,10 @@
1242
  }
1243
  }
1244
  },
1245
- "position": {
1246
- "x": 666.0,
1247
- "y": 492.0
1248
- },
1249
  "type": "basic"
1250
  },
1251
  "params": {
1252
- "epochs": "1000",
1253
  "input_mapping": "{\"map\":{\"Input__embedding_1_x\":{\"column\":\"x\",\"df\":\"df_train\"},\"Input__label_1_y\":{\"column\":\"y\",\"df\":\"df_train\"}}}",
1254
  "model_name": "model"
1255
  },
@@ -1270,49 +1291,52 @@
1270
  "data": {
1271
  "__execution_delay": 0.0,
1272
  "collapsed": null,
1273
- "display": {
1274
- "dataframes": {
1275
- "df": {
1276
- "columns": [
1277
- "x",
1278
- "y"
1279
- ]
1280
- },
1281
- "df_test": {
1282
- "columns": [
1283
- "predicted",
1284
- "x",
1285
- "y"
1286
- ]
 
 
 
 
 
 
 
 
 
 
1287
  },
1288
- "df_train": {
1289
- "columns": [
1290
- "x",
1291
- "y"
1292
- ]
1293
- }
1294
- },
1295
- "other": {
1296
- "model": {
1297
  "model": {
1298
- "inputs": [
1299
- "Input__embedding_1_x"
1300
- ],
1301
- "loss_inputs": [
1302
- "Input__label_1_y",
1303
- "Activation_2_x"
1304
- ],
1305
- "outputs": [
1306
- "Activation_2_x"
1307
- ],
1308
- "trained": true
1309
- },
1310
- "type": "model"
1311
- }
1312
- },
1313
- "relations": []
1314
- },
1315
- "error": null,
 
1316
  "meta": {
1317
  "inputs": {
1318
  "bundle": {
@@ -1356,10 +1380,6 @@
1356
  }
1357
  }
1358
  },
1359
- "position": {
1360
- "x": 934.0,
1361
- "y": 167.0
1362
- },
1363
  "type": "basic"
1364
  },
1365
  "params": {
 
42
  "data": {
43
  "__execution_delay": 0.0,
44
  "collapsed": null,
45
+ "display": null,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  "error": null,
47
+ "input_metadata": [
48
+ {
49
+ "dataframes": {
50
+ "df": {
51
+ "columns": [
52
+ "x",
53
+ "y"
54
+ ]
55
+ }
56
+ },
57
+ "other": {},
58
+ "relations": []
59
+ }
60
+ ],
61
  "meta": {
62
  "inputs": {
63
  "bundle": {
 
119
  "collapsed": null,
120
  "display": null,
121
  "error": null,
122
+ "input_metadata": [],
123
  "meta": {
124
  "inputs": {},
125
  "name": "Import Parquet",
 
579
  ],
580
  "data": [
581
  [
582
+ "[0.49691743 0.61873293 0.90698647 0.94486356]",
583
+ "[1.49691749 1.61873293 1.90698647 1.94486356]",
584
+ "[1.4993021488189697, 1.6404846906661987, 1.923316240310669, 1.9422152042388916]"
585
  ],
586
  [
587
+ "[0.56922203 0.98222166 0.76851749 0.28615737]",
588
+ "[1.56922197 1.9822216 1.76851749 1.28615737]",
589
+ "[1.5835213661193848, 1.9884355068206787, 1.7694181203842163, 1.2917503118515015]"
590
  ],
591
  [
592
+ "[0.90817457 0.89270043 0.38583666 0.66566533]",
593
+ "[1.90817451 1.89270043 1.3858366 1.66566539]",
594
+ "[1.9053494930267334, 1.9083378314971924, 1.3998609781265259, 1.6636812686920166]"
595
  ],
596
  [
597
+ "[0.72795159 0.79317838 0.27832931 0.96576637]",
598
+ "[1.72795153 1.79317832 1.27832937 1.96576643]",
599
+ "[1.734963297843933, 1.8026459217071533, 1.2926064729690552, 1.9596911668777466]"
600
  ],
601
  [
602
+ "[0.04508126 0.76880038 0.80721325 0.62542385]",
603
+ "[1.04508126 1.76880038 1.80721331 1.62542391]",
604
+ "[1.0830243825912476, 1.7584562301635742, 1.8005754947662354, 1.6277496814727783]"
605
  ],
606
  [
607
+ "[0.6032477 0.83361369 0.18538666 0.19108021]",
608
+ "[1.60324764 1.83361363 1.18538666 1.19108021]",
609
+ "[1.6177492141723633, 1.8144152164459229, 1.1718573570251465, 1.1950569152832031]"
610
  ],
611
  [
612
+ "[0.15064228 0.03198934 0.25754827 0.51484001]",
613
+ "[1.15064228 1.03198934 1.25754833 1.51484001]",
614
+ "[1.1556042432785034, 0.9955940246582031, 1.2316606044769287, 1.5150485038757324]"
615
  ],
616
  [
617
+ "[0.48959708 0.48549271 0.32688856 0.356677 ]",
618
+ "[1.48959708 1.48549271 1.32688856 1.35667706]",
619
+ "[1.4930214881896973, 1.467790961265564, 1.3132573366165161, 1.3589863777160645]"
620
  ],
621
  [
622
+ "[0.08107251 0.2602725 0.18861133 0.44833237]",
623
+ "[1.08107257 1.2602725 1.18861127 1.44833231]",
624
+ "[1.102121114730835, 1.2180893421173096, 1.160165548324585, 1.4495322704315186]"
625
  ],
626
  [
627
+ "[0.68094063 0.45189077 0.22661722 0.37354094]",
628
+ "[1.68094063 1.45189071 1.22661722 1.37354088]",
629
+ "[1.6725687980651855, 1.4393560886383057, 1.2169336080551147, 1.3746893405914307]"
630
  ]
631
  ]
632
  },
 
636
  "y"
637
  ],
638
  "data": [
639
+ [
640
+ "[0.52046251 0.45887971 0.72169858 0.29517919]",
641
+ "[1.52046251 1.45887971 1.72169852 1.29517913]"
642
+ ],
643
  [
644
  "[0.85706753 0.61447072 0.41741937 0.85147089]",
645
  "[1.85706758 1.61447072 1.41741943 1.85147095]"
 
672
  "[4.27091718e-01 4.89909172e-01 6.92297399e-01 2.57611275e-04]",
673
  "[1.42709172 1.48990917 1.69229746 1.00025761]"
674
  ],
675
+ [
676
+ "[0.32225502 0.16999388 0.05823922 0.9628762 ]",
677
+ "[1.32225502 1.16999388 1.05823922 1.9628762 ]"
678
+ ],
679
  [
680
  "[0.50783676 0.04156506 0.21984279 0.8454656 ]",
681
  "[1.50783682 1.04156506 1.21984279 1.84546566]"
 
688
  "[0.11693293 0.49860179 0.55020827 0.88832849]",
689
  "[1.11693287 1.49860179 1.55020833 1.88832855]"
690
  ],
 
 
 
 
691
  [
692
  "[0.50272274 0.54912758 0.17663097 0.79070699]",
693
  "[1.50272274 1.54912758 1.17663097 1.79070699]"
694
  ],
 
 
 
 
695
  [
696
  "[0.19908059 0.17570406 0.51475513 0.1893943 ]",
697
  "[1.19908059 1.175704 1.51475513 1.18939424]"
 
709
  "[1.24388778 1.07268476 1.68350863 1.73431659]"
710
  ],
711
  [
712
+ "[0.62569475 0.9881897 0.83639616 0.9828859 ]",
713
+ "[1.62569475 1.9881897 1.83639622 1.98288584]"
714
  ],
715
  [
716
  "[0.88776821 0.51636773 0.30333066 0.32230979]",
717
  "[1.88776827 1.51636767 1.30333066 1.32230973]"
718
  ],
 
 
 
 
719
  [
720
  "[0.48507756 0.80808765 0.77162558 0.47834778]",
721
  "[1.48507762 1.80808759 1.77162552 1.47834778]"
 
740
  "[0.23942459 0.90487361 0.69337189 0.65089428]",
741
  "[1.23942459 1.90487361 1.69337189 1.65089428]"
742
  ],
743
+ [
744
+ "[0.94516498 0.08422136 0.5608117 0.07652664]",
745
+ "[1.94516492 1.08422136 1.56081176 1.07652664]"
746
+ ],
747
+ [
748
+ "[0.26661873 0.45946234 0.13510543 0.81294441]",
749
+ "[1.26661873 1.4594624 1.13510537 1.81294441]"
750
+ ],
751
  [
752
  "[0.30754459 0.77694583 0.09278506 0.38326019]",
753
  "[1.30754459 1.77694583 1.09278512 1.38326025]"
 
756
  "[0.27845025 0.32472342 0.82203609 0.77107543]",
757
  "[1.27845025 1.32472348 1.82203603 1.77107549]"
758
  ],
759
+ [
760
+ "[0.4827103 0.10563457 0.98858833 0.82286644]",
761
+ "[1.48271036 1.10563457 1.98858833 1.82286644]"
762
+ ],
763
  [
764
  "[0.98033333 0.97656083 0.38939917 0.81491041]",
765
  "[1.98033333 1.97656083 1.38939917 1.81491041]"
 
816
  "[0.77427191 0.21829212 0.12769502 0.74303615]",
817
  "[1.77427197 1.21829212 1.12769508 1.74303615]"
818
  ],
 
 
 
 
819
  [
820
  "[0.59812403 0.78395379 0.0291847 0.81814629]",
821
  "[1.59812403 1.78395379 1.0291847 1.81814623]"
 
836
  "[0.85566247 0.83362883 0.48424995 0.25265992]",
837
  "[1.85566247 1.83362889 1.48424995 1.25265992]"
838
  ],
839
+ [
840
+ "[0.95928186 0.84273899 0.71514636 0.38619852]",
841
+ "[1.95928192 1.84273899 1.7151463 1.38619852]"
842
+ ],
843
  [
844
  "[0.32565445 0.90939188 0.07488042 0.13730896]",
845
  "[1.32565451 1.90939188 1.07488036 1.13730896]"
 
852
  "[0.79905868 0.89367443 0.75429088 0.3190186 ]",
853
  "[1.79905868 1.89367437 1.75429082 1.3190186 ]"
854
  ],
855
+ [
856
+ "[0.54914117 0.03810108 0.87531954 0.73044223]",
857
+ "[1.54914117 1.03810108 1.87531948 1.73044229]"
858
+ ],
859
  [
860
  "[0.67418337 0.79634351 0.23229051 0.71345252]",
861
  "[1.67418337 1.79634356 1.23229051 1.71345258]"
 
900
  "[0.47963417 0.81818312 0.48720706 0.49339259]",
901
  "[1.47963417 1.81818318 1.48720706 1.49339259]"
902
  ],
903
+ [
904
+ "[0.9630242 0.76359051 0.24853623 0.76881069]",
905
+ "[1.96302414 1.76359057 1.24853623 1.76881075]"
906
+ ],
907
  [
908
  "[0.60609657 0.96257663 0.19292736 0.95702219]",
909
  "[1.60609651 1.96257663 1.19292736 1.95702219]"
 
924
  "[0.59492421 0.90274489 0.38069052 0.46101224]",
925
  "[1.59492421 1.90274489 1.38069057 1.46101224]"
926
  ],
 
 
 
 
927
  [
928
  "[0.12024075 0.21342516 0.56858408 0.58644271]",
929
  "[1.12024069 1.21342516 1.56858408 1.58644271]"
930
  ],
931
  [
932
+ "[0.91730917 0.22574073 0.09591609 0.33056474]",
933
+ "[1.91730917 1.22574067 1.09591603 1.33056474]"
 
 
 
 
934
  ],
935
  [
936
  "[0.63235509 0.70352674 0.96188956 0.46240485]",
 
980
  "[0.28942841 0.05601001 0.33039129 0.27781558]",
981
  "[1.28942847 1.05601001 1.33039129 1.27781558]"
982
  ],
 
 
 
 
983
  [
984
  "[0.43681622 0.74680805 0.83598751 0.12414402]",
985
  "[1.43681622 1.74680805 1.83598757 1.12414408]"
 
988
  "[0.47870928 0.17129105 0.27300501 0.20634609]",
989
  "[1.47870922 1.17129111 1.27300501 1.20634604]"
990
  ],
 
 
 
 
991
  [
992
  "[0.87608397 0.93200487 0.80169648 0.37758952]",
993
  "[1.87608397 1.93200493 1.80169654 1.37758946]"
 
1000
  }
1001
  },
1002
  "other": {
1003
+ "model": "ModelConfig(model=Sequential(\n (0) - Linear(in_features=4, out_features=4, bias=True): Input__embedding_1_x -> Linear_1_x\n (1) - <function leaky_relu at 0x719e0ce23a60>: Linear_1_x -> Activation_2_x\n (2) - Identity(): Activation_2_x -> Activation_2_x\n), model_inputs=['Input__embedding_1_x'], model_outputs=['Activation_2_x'], loss_inputs=['Input__label_1_y', 'Activation_2_x'], loss=Sequential(\n (0) - <function mse_loss at 0x719e0ce2d580>: Activation_2_x, Input__label_1_y -> MSE_loss_1_loss\n (1) - Identity(): MSE_loss_1_loss -> loss\n), optimizer=SGD (\nParameter Group 0\n dampening: 0\n differentiable: False\n foreach: None\n fused: None\n lr: 0.1\n maximize: False\n momentum: 0\n nesterov: False\n weight_decay: 0\n), source_workspace=None, trained=True)"
1004
  },
1005
  "relations": []
1006
  },
1007
  "error": null,
1008
+ "input_metadata": [
1009
+ {
1010
+ "dataframes": {
1011
+ "df": {
1012
+ "columns": [
1013
+ "x",
1014
+ "y"
1015
+ ]
1016
+ },
1017
+ "df_test": {
1018
+ "columns": [
1019
+ "predicted",
1020
+ "x",
1021
+ "y"
1022
+ ]
1023
+ },
1024
+ "df_train": {
1025
+ "columns": [
1026
+ "x",
1027
+ "y"
1028
+ ]
1029
+ }
1030
+ },
1031
+ "other": {
1032
+ "model": {
1033
+ "model": {
1034
+ "inputs": [
1035
+ "Input__embedding_1_x"
1036
+ ],
1037
+ "loss_inputs": [
1038
+ "Input__label_1_y",
1039
+ "Activation_2_x"
1040
+ ],
1041
+ "outputs": [
1042
+ "Activation_2_x"
1043
+ ],
1044
+ "trained": true
1045
+ },
1046
+ "type": "model"
1047
+ }
1048
+ },
1049
+ "relations": []
1050
+ }
1051
+ ],
1052
  "meta": {
1053
  "inputs": {
1054
  "bundle": {
 
1092
  "data": {
1093
  "__execution_delay": 0.0,
1094
  "collapsed": null,
1095
+ "display": null,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1096
  "error": null,
1097
+ "input_metadata": [
1098
+ {
1099
+ "dataframes": {
1100
+ "df": {
1101
+ "columns": [
1102
+ "x",
1103
+ "y"
1104
+ ]
1105
+ },
1106
+ "df_test": {
1107
+ "columns": [
1108
+ "x",
1109
+ "y"
1110
+ ]
1111
+ },
1112
+ "df_train": {
1113
+ "columns": [
1114
+ "x",
1115
+ "y"
1116
+ ]
1117
+ }
1118
+ },
1119
+ "other": {},
1120
+ "relations": []
1121
+ }
1122
+ ],
1123
  "meta": {
1124
  "inputs": {
1125
  "bundle": {
 
1179
  "data": {
1180
  "__execution_delay": 0.0,
1181
  "collapsed": null,
1182
+ "display": null,
1183
+ "error": null,
1184
+ "input_metadata": [
1185
+ {
1186
+ "dataframes": {
1187
+ "df": {
1188
+ "columns": [
1189
+ "x",
1190
+ "y"
1191
+ ]
1192
+ },
1193
+ "df_test": {
1194
+ "columns": [
1195
+ "x",
1196
+ "y"
1197
+ ]
1198
+ },
1199
+ "df_train": {
1200
+ "columns": [
1201
+ "x",
1202
+ "y"
1203
+ ]
1204
+ }
1205
  },
1206
+ "other": {
 
 
 
 
 
 
 
 
1207
  "model": {
1208
+ "model": {
1209
+ "inputs": [
1210
+ "Input__embedding_1_x"
1211
+ ],
1212
+ "loss_inputs": [
1213
+ "Input__label_1_y",
1214
+ "Activation_2_x"
1215
+ ],
1216
+ "outputs": [
1217
+ "Activation_2_x"
1218
+ ],
1219
+ "trained": false
1220
+ },
1221
+ "type": "model"
1222
+ }
1223
+ },
1224
+ "relations": []
1225
+ }
1226
+ ],
1227
  "meta": {
1228
  "inputs": {
1229
  "bundle": {
 
1267
  }
1268
  }
1269
  },
 
 
 
 
1270
  "type": "basic"
1271
  },
1272
  "params": {
1273
+ "epochs": "1001",
1274
  "input_mapping": "{\"map\":{\"Input__embedding_1_x\":{\"column\":\"x\",\"df\":\"df_train\"},\"Input__label_1_y\":{\"column\":\"y\",\"df\":\"df_train\"}}}",
1275
  "model_name": "model"
1276
  },
 
1291
  "data": {
1292
  "__execution_delay": 0.0,
1293
  "collapsed": null,
1294
+ "display": null,
1295
+ "error": null,
1296
+ "input_metadata": [
1297
+ {
1298
+ "dataframes": {
1299
+ "df": {
1300
+ "columns": [
1301
+ "x",
1302
+ "y"
1303
+ ]
1304
+ },
1305
+ "df_test": {
1306
+ "columns": [
1307
+ "predicted",
1308
+ "x",
1309
+ "y"
1310
+ ]
1311
+ },
1312
+ "df_train": {
1313
+ "columns": [
1314
+ "x",
1315
+ "y"
1316
+ ]
1317
+ }
1318
  },
1319
+ "other": {
 
 
 
 
 
 
 
 
1320
  "model": {
1321
+ "model": {
1322
+ "inputs": [
1323
+ "Input__embedding_1_x"
1324
+ ],
1325
+ "loss_inputs": [
1326
+ "Input__label_1_y",
1327
+ "Activation_2_x"
1328
+ ],
1329
+ "outputs": [
1330
+ "Activation_2_x"
1331
+ ],
1332
+ "trained": true
1333
+ },
1334
+ "type": "model"
1335
+ }
1336
+ },
1337
+ "relations": []
1338
+ }
1339
+ ],
1340
  "meta": {
1341
  "inputs": {
1342
  "bundle": {
 
1380
  }
1381
  }
1382
  },
 
 
 
 
1383
  "type": "basic"
1384
  },
1385
  "params": {
lynxkite-app/src/lynxkite_app/crdt.py CHANGED
@@ -90,6 +90,7 @@ last_ws_input = None
90
  def clean_input(ws_pyd):
91
  for node in ws_pyd.nodes:
92
  node.data.display = None
 
93
  node.data.error = None
94
  node.data.status = workspace.NodeStatus.done
95
  node.position.x = 0
@@ -168,9 +169,12 @@ def try_to_load_workspace(ws: pycrdt.Map, name: str):
168
  """
169
  if os.path.exists(name):
170
  ws_pyd = workspace.load(name)
171
- # We treat the display field as a black box, since it is a large
172
- # dictionary that is meant to change as a whole.
173
- crdt_update(ws, ws_pyd.model_dump(), non_collaborative_fields={"display"})
 
 
 
174
 
175
 
176
  last_known_versions = {}
 
90
  def clean_input(ws_pyd):
91
  for node in ws_pyd.nodes:
92
  node.data.display = None
93
+ node.data.input_metadata = None
94
  node.data.error = None
95
  node.data.status = workspace.NodeStatus.done
96
  node.position.x = 0
 
169
  """
170
  if os.path.exists(name):
171
  ws_pyd = workspace.load(name)
172
+ crdt_update(
173
+ ws,
174
+ ws_pyd.model_dump(),
175
+ # We treat some fields as black boxes. They are not edited on the frontend.
176
+ non_collaborative_fields={"display", "input_metadata"},
177
+ )
178
 
179
 
180
  last_known_versions = {}
lynxkite-app/tests/test_main.py CHANGED
@@ -37,6 +37,7 @@ def test_save_and_load():
37
  "type": "basic",
38
  "data": {
39
  "display": None,
 
40
  "error": "Unknown operation.",
41
  "title": "Test node",
42
  "params": {"param1": "value"},
 
37
  "type": "basic",
38
  "data": {
39
  "display": None,
40
+ "input_metadata": None,
41
  "error": "Unknown operation.",
42
  "title": "Test node",
43
  "params": {"param1": "value"},
lynxkite-app/web/playwright.config.ts CHANGED
@@ -24,7 +24,7 @@ export default defineConfig({
24
  ],
25
  webServer: {
26
  command: "cd ../../examples && lynxkite",
27
- url: "http://127.0.0.1:8000",
28
  reuseExistingServer: false,
29
  },
30
  });
 
24
  ],
25
  webServer: {
26
  command: "cd ../../examples && lynxkite",
27
+ port: 8000,
28
  reuseExistingServer: false,
29
  },
30
  });
lynxkite-app/web/src/apiTypes.ts CHANGED
@@ -5,6 +5,8 @@
5
  /* Do not modify it by hand - just update the pydantic models and then re-run the script
6
  */
7
 
 
 
8
  export interface DirectoryEntry {
9
  name: string;
10
  type: string;
@@ -40,8 +42,9 @@ export interface WorkspaceNodeData {
40
  [k: string]: unknown;
41
  };
42
  display?: unknown;
 
43
  error?: string | null;
44
- in_progress?: boolean;
45
  [k: string]: unknown;
46
  }
47
  export interface Position {
 
5
  /* Do not modify it by hand - just update the pydantic models and then re-run the script
6
  */
7
 
8
+ export type NodeStatus = "planned" | "active" | "done";
9
+
10
  export interface DirectoryEntry {
11
  name: string;
12
  type: string;
 
42
  [k: string]: unknown;
43
  };
44
  display?: unknown;
45
+ input_metadata?: unknown;
46
  error?: string | null;
47
+ status?: NodeStatus;
48
  [k: string]: unknown;
49
  }
50
  export interface Position {
lynxkite-app/web/src/workspace/nodes/NodeGroupParameter.tsx CHANGED
@@ -24,6 +24,7 @@ interface GroupsType {
24
  interface NodeGroupParameterProps {
25
  meta: { selector: SelectorType; groups: GroupsType };
26
  value: any;
 
27
  setParam: (name: string, value: any, options?: { delay: number }) => void;
28
  deleteParam: (name: string, options?: { delay: number }) => void;
29
  }
@@ -31,6 +32,7 @@ interface NodeGroupParameterProps {
31
  export default function NodeGroupParameter({
32
  meta,
33
  value,
 
34
  setParam,
35
  deleteParam,
36
  }: NodeGroupParameterProps) {
@@ -60,6 +62,7 @@ export default function NodeGroupParameter({
60
  name={selector.name}
61
  key={selector.name}
62
  value={selectedValue}
 
63
  meta={selector}
64
  onChange={handleSelectorChange}
65
  />
 
24
  interface NodeGroupParameterProps {
25
  meta: { selector: SelectorType; groups: GroupsType };
26
  value: any;
27
+ data: any;
28
  setParam: (name: string, value: any, options?: { delay: number }) => void;
29
  deleteParam: (name: string, options?: { delay: number }) => void;
30
  }
 
32
  export default function NodeGroupParameter({
33
  meta,
34
  value,
35
+ data,
36
  setParam,
37
  deleteParam,
38
  }: NodeGroupParameterProps) {
 
62
  name={selector.name}
63
  key={selector.name}
64
  value={selectedValue}
65
+ data={data}
66
  meta={selector}
67
  onChange={handleSelectorChange}
68
  />
lynxkite-app/web/src/workspace/nodes/NodeParameter.tsx CHANGED
@@ -52,11 +52,14 @@ function getModelBindings(
52
  }
53
  }
54
  const bindings = new Set<string>();
55
- const other = data?.display?.other ?? data?.display?.value?.other ?? {};
56
- for (const e of Object.values(other) as any[]) {
57
- if (e.type === "model") {
58
- for (const b of bindingsOfModel(e.model)) {
59
- bindings.add(b);
 
 
 
60
  }
61
  }
62
  }
@@ -78,15 +81,20 @@ function parseJsonOrEmpty(json: string): object {
78
  function ModelMapping({ value, onChange, data, variant }: any) {
79
  const v: any = parseJsonOrEmpty(value);
80
  v.map ??= {};
81
- const dfs =
82
- data?.display?.dataframes ?? data?.display?.value?.dataframes ?? {};
 
 
 
 
 
 
 
 
83
  const bindings = getModelBindings(data, variant);
84
  return (
85
  <table className="model-mapping-param">
86
  <tbody>
87
- <tr>
88
- <td>mm</td>
89
- </tr>
90
  {bindings.length > 0 ? (
91
  bindings.map((binding: string) => (
92
  <tr key={binding}>
@@ -105,7 +113,7 @@ function ModelMapping({ value, onChange, data, variant }: any) {
105
  onChange(JSON.stringify({ map }));
106
  } else {
107
  const columnSpec = {
108
- column: dfs[df].columns[0],
109
  ...(v.map?.[binding] || {}),
110
  df,
111
  };
@@ -149,7 +157,7 @@ function ModelMapping({ value, onChange, data, variant }: any) {
149
  onChange(JSON.stringify({ map }));
150
  }}
151
  >
152
- {dfs[v.map?.[binding]?.df]?.columns.map((col: string) => (
153
  <option key={col} value={col}>
154
  {col}
155
  </option>
@@ -221,13 +229,13 @@ export default function NodeParameter({
221
  ) : meta?.type?.type === BOOLEAN ? (
222
  <div className="form-control">
223
  <label className="label cursor-pointer">
 
224
  <input
225
  className="checkbox"
226
  type="checkbox"
227
  checked={value}
228
  onChange={(evt) => onChange(evt.currentTarget.checked)}
229
  />
230
- {name.replace(/_/g, " ")}
231
  </label>
232
  </div>
233
  ) : meta?.type?.type === MODEL_TRAINING_INPUT_MAPPING ? (
 
52
  }
53
  }
54
  const bindings = new Set<string>();
55
+ const inputs = data?.input_metadata?.value ?? data?.input_metadata ?? [];
56
+ for (const input of inputs) {
57
+ const other = input.other ?? {};
58
+ for (const e of Object.values(other) as any[]) {
59
+ if (e.type === "model") {
60
+ for (const b of bindingsOfModel(e.model)) {
61
+ bindings.add(b);
62
+ }
63
  }
64
  }
65
  }
 
81
  function ModelMapping({ value, onChange, data, variant }: any) {
82
  const v: any = parseJsonOrEmpty(value);
83
  v.map ??= {};
84
+ const dfs: { [df: string]: string[] } = {};
85
+ const inputs = data?.input_metadata?.value ?? data?.input_metadata ?? [];
86
+ for (const input of inputs) {
87
+ const dataframes = input.dataframes as {
88
+ [df: string]: { columns: string[] };
89
+ };
90
+ for (const [df, { columns }] of Object.entries(dataframes)) {
91
+ dfs[df] = columns;
92
+ }
93
+ }
94
  const bindings = getModelBindings(data, variant);
95
  return (
96
  <table className="model-mapping-param">
97
  <tbody>
 
 
 
98
  {bindings.length > 0 ? (
99
  bindings.map((binding: string) => (
100
  <tr key={binding}>
 
113
  onChange(JSON.stringify({ map }));
114
  } else {
115
  const columnSpec = {
116
+ column: dfs[df][0],
117
  ...(v.map?.[binding] || {}),
118
  df,
119
  };
 
157
  onChange(JSON.stringify({ map }));
158
  }}
159
  >
160
+ {dfs[v.map?.[binding]?.df]?.map((col: string) => (
161
  <option key={col} value={col}>
162
  {col}
163
  </option>
 
229
  ) : meta?.type?.type === BOOLEAN ? (
230
  <div className="form-control">
231
  <label className="label cursor-pointer">
232
+ {name.replace(/_/g, " ")}
233
  <input
234
  className="checkbox"
235
  type="checkbox"
236
  checked={value}
237
  onChange={(evt) => onChange(evt.currentTarget.checked)}
238
  />
 
239
  </label>
240
  </div>
241
  ) : meta?.type?.type === MODEL_TRAINING_INPUT_MAPPING ? (
lynxkite-app/web/src/workspace/nodes/NodeWithParams.tsx CHANGED
@@ -49,6 +49,7 @@ function NodeWithParams(props: any) {
49
  <NodeGroupParameter
50
  key={name}
51
  value={value}
 
52
  meta={metaParams?.[name]}
53
  setParam={(name: string, value: any, opts?: UpdateOptions) =>
54
  setParam(name, value, opts || {})
 
49
  <NodeGroupParameter
50
  key={name}
51
  value={value}
52
+ data={props.data}
53
  meta={metaParams?.[name]}
54
  setParam={(name: string, value: any, opts?: UpdateOptions) =>
55
  setParam(name, value, opts || {})
lynxkite-core/src/lynxkite/core/ops.py CHANGED
@@ -106,18 +106,13 @@ class Result:
106
  The `output` attribute is what will be used as input for other operations.
107
  The `display` attribute is used to send data to display on the UI. The value has to be
108
  JSON-serializable.
 
109
  """
110
 
111
  output: typing.Any = None
112
  display: ReadOnlyJSON | None = None
113
  error: str | None = None
114
-
115
- def default_display(self) -> ReadOnlyJSON | None:
116
- """Automatically extracts basic data from the output."""
117
- if hasattr(self.output, "default_display"):
118
- return self.output.default_display()
119
- else:
120
- return None
121
 
122
 
123
  MULTI_INPUT = Input(name="multi", type="*")
@@ -147,7 +142,7 @@ def _param_to_type(name, value, type):
147
  return None if value == "" else _param_to_type(name, value, type)
148
  case (type, types.NoneType):
149
  return None if value == "" else _param_to_type(name, value, type)
150
- if issubclass(type, pydantic.BaseModel):
151
  try:
152
  return type.model_validate_json(value)
153
  except pydantic.ValidationError:
 
106
  The `output` attribute is what will be used as input for other operations.
107
  The `display` attribute is used to send data to display on the UI. The value has to be
108
  JSON-serializable.
109
+ `input_metadata` is a list of JSON objects describing each input.
110
  """
111
 
112
  output: typing.Any = None
113
  display: ReadOnlyJSON | None = None
114
  error: str | None = None
115
+ input_metadata: ReadOnlyJSON | None = None
 
 
 
 
 
 
116
 
117
 
118
  MULTI_INPUT = Input(name="multi", type="*")
 
142
  return None if value == "" else _param_to_type(name, value, type)
143
  case (type, types.NoneType):
144
  return None if value == "" else _param_to_type(name, value, type)
145
+ if isinstance(type, typeof) and issubclass(type, pydantic.BaseModel):
146
  try:
147
  return type.model_validate_json(value)
148
  except pydantic.ValidationError:
lynxkite-core/src/lynxkite/core/workspace.py CHANGED
@@ -32,6 +32,7 @@ class WorkspaceNodeData(BaseConfig):
32
  title: str
33
  params: dict
34
  display: Optional[object] = None
 
35
  error: Optional[str] = None
36
  status: NodeStatus = NodeStatus.done
37
  # Also contains a "meta" field when going out.
@@ -59,13 +60,13 @@ class WorkspaceNode(BaseConfig):
59
  def publish_result(self, result: ops.Result):
60
  """Sends the result to the frontend. Call this in an executor when the result is available."""
61
  self.data.display = result.display
62
- if self.data.display is None:
63
- self.data.display = result.default_display()
64
  self.data.error = result.error
65
  self.data.status = NodeStatus.done
66
  if hasattr(self, "_crdt"):
67
  with self._crdt.doc.transaction():
68
  self._crdt["data"]["display"] = self.data.display
 
69
  self._crdt["data"]["error"] = self.data.error
70
  self._crdt["data"]["status"] = NodeStatus.done
71
 
 
32
  title: str
33
  params: dict
34
  display: Optional[object] = None
35
+ input_metadata: Optional[object] = None
36
  error: Optional[str] = None
37
  status: NodeStatus = NodeStatus.done
38
  # Also contains a "meta" field when going out.
 
60
  def publish_result(self, result: ops.Result):
61
  """Sends the result to the frontend. Call this in an executor when the result is available."""
62
  self.data.display = result.display
63
+ self.data.input_metadata = result.input_metadata
 
64
  self.data.error = result.error
65
  self.data.status = NodeStatus.done
66
  if hasattr(self, "_crdt"):
67
  with self._crdt.doc.transaction():
68
  self._crdt["data"]["display"] = self.data.display
69
+ self._crdt["data"]["input_metadata"] = self.data.input_metadata
70
  self._crdt["data"]["error"] = self.data.error
71
  self._crdt["data"]["status"] = NodeStatus.done
72
 
lynxkite-graph-analytics/src/lynxkite_graph_analytics/core.py CHANGED
@@ -119,7 +119,7 @@ class Bundle:
119
  "other": {k: str(v) for k, v in self.other.items()},
120
  }
121
 
122
- def default_display(self):
123
  """JSON-serializable information about the bundle, metadata only."""
124
  return {
125
  "dataframes": {
@@ -130,8 +130,7 @@ class Bundle:
130
  },
131
  "relations": [dataclasses.asdict(relation) for relation in self.relations],
132
  "other": {
133
- k: getattr(v, "default_display", lambda: {})()
134
- for k, v in self.other.items()
135
  },
136
  }
137
 
@@ -231,15 +230,18 @@ def _execute_node(node, ws, catalog, outputs):
231
  if os.environ.get("LYNXKITE_LOG_OP_ERRORS"):
232
  traceback.print_exc()
233
  result = ops.Result(error=str(e))
234
- # On error, just output the first input. This helps reduce the errors on the frontend,
235
- # and it lets boxes easily access things from their inputs on the UI, even in error state.
236
- if inputs:
237
- result.output = inputs[0]
238
  if result.output is not None:
239
  outputs[node.id] = result.output
240
  node.publish_result(result)
241
 
242
 
 
 
 
 
 
 
243
  def df_for_frontend(df: pd.DataFrame, limit: int) -> pd.DataFrame:
244
  """Returns a DataFrame with values that are safe to send to the frontend."""
245
  df = df[:limit]
 
119
  "other": {k: str(v) for k, v in self.other.items()},
120
  }
121
 
122
+ def metadata(self):
123
  """JSON-serializable information about the bundle, metadata only."""
124
  return {
125
  "dataframes": {
 
130
  },
131
  "relations": [dataclasses.asdict(relation) for relation in self.relations],
132
  "other": {
133
+ k: getattr(v, "metadata", lambda: {})() for k, v in self.other.items()
 
134
  },
135
  }
136
 
 
230
  if os.environ.get("LYNXKITE_LOG_OP_ERRORS"):
231
  traceback.print_exc()
232
  result = ops.Result(error=str(e))
233
+ result.input_metadata = [_get_metadata(i) for i in inputs]
 
 
 
234
  if result.output is not None:
235
  outputs[node.id] = result.output
236
  node.publish_result(result)
237
 
238
 
239
+ def _get_metadata(x):
240
+ if hasattr(x, "metadata"):
241
+ return x.metadata()
242
+ return {}
243
+
244
+
245
  def df_for_frontend(df: pd.DataFrame, limit: int) -> pd.DataFrame:
246
  """Returns a DataFrame with values that are safe to send to the frontend."""
247
  df = df[:limit]
lynxkite-graph-analytics/src/lynxkite_graph_analytics/pytorch_model_ops.py CHANGED
@@ -184,7 +184,7 @@ class ModelConfig:
184
  c.model = copy.deepcopy(self.model)
185
  return c
186
 
187
- def default_display(self):
188
  return {
189
  "type": "model",
190
  "model": {
 
184
  c.model = copy.deepcopy(self.model)
185
  return c
186
 
187
+ def metadata(self):
188
  return {
189
  "type": "model",
190
  "model": {