@fastino-ai/pioneer-cli 0.2.6 → 0.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -71
- package/package.json +7 -2
- package/src/api.ts +1331 -213
- package/src/client/WebSocketClient.ts +25 -7
- package/src/config.ts +8 -1
- package/src/index.tsx +2612 -468
- package/.claude/settings.local.json +0 -38
- package/.cursor/rules/api-documentation.mdc +0 -17
- package/.cursor/rules/backend-location-rule.mdc +0 -5
- package/.github/workflows/pioneer-cli-tests.yml +0 -44
- package/Medical_NER_Dataset_1.jsonl +0 -50
- package/REPRODUCTION_REPORT.md +0 -195
- package/alphago_reproduction.ipynb +0 -902
- package/bun.lock +0 -264
- package/cache/cache.db +0 -0
- package/cache/cache.db-shm +0 -0
- package/cache/cache.db-wal +0 -0
- package/compare_results.py +0 -141
- package/datasets/Medical_NER_Dataset.json +0 -2609
- package/datasets/ner-dataset.json +0 -57
- package/datasets/test-remote.json +0 -41
- package/datasets/test-warning.json +0 -49
- package/install.sh +0 -68
- package/monitor_and_test.py +0 -111
- package/quick_test.py +0 -39
- package/reproduce_degradation.py +0 -147
- package/tsconfig.json +0 -22
- package/workspaces/0-skinny-mink-of-management/input/private/test.csv +0 -100
- package/workspaces/0-skinny-mink-of-management/input/public/description.md +0 -70
- package/workspaces/0-skinny-mink-of-management/input/public/images/1.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/10.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/100.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1000.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1001.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1002.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1003.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1004.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1005.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1006.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1007.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/101.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1010.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1011.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1013.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1014.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1016.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1017.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1019.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1021.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1023.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1024.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1025.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1027.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/103.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1030.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1031.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1032.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1034.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1036.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1037.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1039.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1040.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1041.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1042.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1046.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1048.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1049.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1051.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1052.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1056.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1059.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/106.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1061.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1062.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1065.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1066.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/107.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1072.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1073.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1076.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1077.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/108.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1080.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1081.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1083.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1085.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1087.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1088.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1089.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/109.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1090.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1093.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1094.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1095.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1096.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1097.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1098.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/11.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1100.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1101.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1110.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1112.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1113.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1117.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1118.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1119.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1120.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1121.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1123.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1124.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1125.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1128.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1130.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1131.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1132.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1134.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1135.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1136.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1142.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1144.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1145.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1147.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1148.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/115.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1152.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1153.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1154.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1156.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1157.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1159.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/116.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1160.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1163.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1165.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1166.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1167.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1168.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1169.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1170.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1171.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1172.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1173.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1174.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1175.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1176.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1179.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/118.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1180.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1182.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1184.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1186.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1187.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1194.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1196.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1197.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1198.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/120.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1200.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1201.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1202.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1205.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1206.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1208.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1210.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1211.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1213.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1216.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1217.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1218.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1219.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/122.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1220.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1221.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1222.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1223.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1225.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1226.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1228.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1229.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1231.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1232.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1235.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1236.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1238.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1239.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/124.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1240.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1242.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1243.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1244.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1245.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1249.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1250.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1251.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1253.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1254.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1255.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1256.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1257.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1258.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1262.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1263.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1265.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1268.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1269.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/127.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1270.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1271.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1273.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1275.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1276.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1277.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1278.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1281.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1282.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1283.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1284.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1286.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1287.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1289.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/129.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1291.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1292.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1294.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1296.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1299.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/130.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1300.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1301.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1302.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1305.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1308.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1309.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1310.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1311.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1312.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1317.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1319.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/132.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1320.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1322.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1323.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1324.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1325.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1326.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1327.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1328.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1329.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/133.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1330.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1335.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1337.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1339.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/134.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1340.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1341.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1342.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1344.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1345.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1346.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1347.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1348.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1349.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1350.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1352.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1353.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1355.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1356.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1358.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1359.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1360.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1365.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1366.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1367.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1370.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1372.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1373.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1374.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1375.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1377.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1378.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1379.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1380.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1381.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1384.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1386.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1388.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/139.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1390.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1391.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1392.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1393.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1394.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1395.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1396.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1398.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1399.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/14.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/140.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1402.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1403.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1405.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1408.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1410.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1411.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1413.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1414.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1417.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1419.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/142.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1420.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1423.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1424.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1425.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/143.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1431.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1432.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1435.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1436.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1438.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1440.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1441.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1442.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1443.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1444.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1446.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1448.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1449.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/145.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1450.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1452.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1454.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1457.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1459.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/146.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1460.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1461.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1463.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1467.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1468.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1469.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1471.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1472.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1473.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1474.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1475.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1476.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1477.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1479.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/148.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1480.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1482.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1483.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1488.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/149.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1491.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1492.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1494.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1496.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1499.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/15.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1500.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1501.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1502.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1504.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1505.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1506.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1507.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1508.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1509.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1511.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1512.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1514.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1515.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1516.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1518.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1519.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/152.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1520.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1521.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1523.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1524.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1525.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1527.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1529.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/153.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1530.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1531.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1532.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1536.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1538.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1539.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1541.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1543.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1544.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1545.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1547.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1548.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1549.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/155.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1550.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1551.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1552.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1554.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1555.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1556.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1557.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1559.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1561.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1562.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1563.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1566.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1568.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1569.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1570.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1571.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1572.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1574.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1575.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1578.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1581.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1582.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/1584.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/160.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/163.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/164.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/165.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/166.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/167.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/168.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/169.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/17.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/171.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/173.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/175.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/178.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/179.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/18.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/183.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/186.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/188.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/189.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/190.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/194.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/196.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/198.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/199.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/2.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/20.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/201.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/202.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/203.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/204.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/206.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/21.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/211.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/212.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/214.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/215.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/216.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/217.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/218.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/219.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/22.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/224.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/225.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/227.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/228.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/231.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/233.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/235.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/237.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/238.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/239.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/240.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/241.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/242.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/243.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/245.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/246.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/247.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/248.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/249.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/25.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/252.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/253.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/256.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/257.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/258.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/259.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/26.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/260.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/262.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/263.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/265.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/267.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/268.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/269.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/27.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/270.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/273.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/275.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/278.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/280.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/282.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/283.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/286.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/288.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/289.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/29.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/290.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/291.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/294.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/298.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/3.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/30.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/302.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/303.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/304.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/306.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/307.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/309.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/31.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/310.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/311.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/314.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/315.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/317.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/319.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/32.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/321.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/322.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/323.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/324.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/325.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/326.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/327.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/328.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/329.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/330.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/331.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/333.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/334.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/335.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/336.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/338.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/339.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/34.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/340.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/341.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/342.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/344.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/345.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/348.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/349.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/35.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/350.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/354.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/355.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/356.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/357.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/358.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/360.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/362.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/363.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/364.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/365.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/366.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/367.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/369.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/37.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/371.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/374.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/375.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/376.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/377.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/379.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/38.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/380.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/382.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/383.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/386.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/387.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/388.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/389.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/390.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/392.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/393.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/394.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/396.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/397.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/398.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/40.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/404.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/408.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/409.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/410.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/411.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/412.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/413.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/415.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/416.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/417.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/418.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/419.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/42.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/420.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/423.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/425.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/426.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/427.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/428.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/43.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/430.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/431.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/433.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/435.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/436.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/437.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/438.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/440.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/443.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/444.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/445.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/446.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/449.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/45.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/450.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/451.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/452.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/454.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/455.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/456.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/458.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/459.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/460.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/461.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/462.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/463.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/464.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/466.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/467.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/468.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/469.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/470.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/475.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/478.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/48.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/481.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/482.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/485.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/487.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/488.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/489.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/49.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/490.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/491.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/492.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/493.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/494.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/496.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/497.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/498.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/499.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/5.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/50.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/501.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/502.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/505.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/506.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/508.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/510.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/511.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/513.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/514.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/516.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/517.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/519.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/520.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/521.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/522.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/523.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/524.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/528.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/530.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/532.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/535.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/538.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/539.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/54.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/542.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/543.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/545.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/547.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/548.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/55.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/550.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/551.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/552.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/553.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/556.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/558.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/559.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/56.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/561.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/562.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/563.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/564.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/566.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/568.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/569.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/570.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/571.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/572.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/573.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/576.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/58.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/581.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/582.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/585.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/588.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/589.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/592.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/593.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/595.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/596.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/597.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/598.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/6.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/60.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/600.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/601.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/603.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/605.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/606.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/609.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/61.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/610.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/614.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/615.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/616.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/618.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/619.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/620.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/621.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/622.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/623.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/628.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/629.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/63.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/630.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/631.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/632.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/633.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/634.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/635.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/636.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/637.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/64.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/641.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/642.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/645.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/646.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/647.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/649.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/651.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/652.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/654.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/656.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/657.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/66.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/660.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/661.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/662.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/663.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/664.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/667.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/669.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/67.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/671.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/672.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/673.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/675.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/676.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/677.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/678.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/680.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/681.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/682.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/684.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/685.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/689.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/69.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/692.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/693.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/694.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/695.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/697.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/698.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/700.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/704.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/706.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/709.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/71.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/710.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/711.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/712.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/713.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/714.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/716.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/717.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/718.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/72.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/720.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/721.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/722.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/724.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/726.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/727.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/728.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/73.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/730.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/732.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/733.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/737.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/738.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/740.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/741.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/742.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/745.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/747.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/748.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/749.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/75.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/752.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/753.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/754.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/755.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/756.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/757.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/758.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/759.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/76.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/760.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/762.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/763.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/765.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/766.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/767.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/768.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/769.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/771.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/772.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/774.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/776.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/777.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/778.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/779.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/78.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/784.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/785.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/787.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/788.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/789.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/792.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/793.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/794.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/796.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/797.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/798.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/8.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/80.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/800.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/801.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/802.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/803.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/805.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/806.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/807.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/808.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/809.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/81.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/810.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/811.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/812.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/813.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/815.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/816.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/82.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/821.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/822.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/823.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/824.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/825.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/826.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/827.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/828.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/83.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/831.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/837.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/838.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/839.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/84.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/840.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/841.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/844.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/847.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/848.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/849.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/85.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/850.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/851.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/852.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/853.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/854.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/855.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/856.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/858.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/859.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/860.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/861.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/862.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/863.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/864.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/865.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/866.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/867.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/868.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/869.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/87.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/870.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/871.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/873.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/874.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/875.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/876.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/877.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/878.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/879.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/88.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/881.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/882.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/883.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/885.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/886.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/892.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/893.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/894.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/896.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/897.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/898.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/899.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/900.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/901.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/904.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/906.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/907.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/908.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/910.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/911.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/912.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/914.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/915.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/916.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/917.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/918.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/919.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/92.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/920.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/923.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/924.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/926.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/927.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/928.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/931.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/932.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/933.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/934.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/936.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/937.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/938.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/939.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/942.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/944.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/948.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/949.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/951.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/952.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/954.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/955.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/956.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/958.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/959.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/960.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/961.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/962.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/963.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/966.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/968.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/969.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/970.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/971.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/972.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/975.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/976.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/978.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/979.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/981.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/983.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/985.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/987.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/989.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/990.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/992.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/993.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/994.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/995.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/996.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/images/999.jpg +0 -0
- package/workspaces/0-skinny-mink-of-management/input/public/sample_submission.csv +0 -100
- package/workspaces/0-skinny-mink-of-management/input/public/test.csv +0 -100
- package/workspaces/0-skinny-mink-of-management/input/public/train.csv +0 -892
- package/workspaces/0-skinny-mink-of-management/working/submission.csv +0 -100
- package/workspaces/santa-2025/EXISTING_SOLUTION_ANALYSIS.md +0 -181
- package/workspaces/santa-2025/FINAL_ANALYSIS_SUMMARY.md +0 -126
- package/workspaces/santa-2025/FINAL_RECOMMENDATION.md +0 -189
- package/workspaces/santa-2025/FINAL_REPORT.md +0 -207
- package/workspaces/santa-2025/INDEX.md +0 -136
- package/workspaces/santa-2025/PROGRESS.md +0 -210
- package/workspaces/santa-2025/QUICK_WINS_ANALYSIS.md +0 -158
- package/workspaces/santa-2025/README.md +0 -165
- package/workspaces/santa-2025/SUMMARY.md +0 -239
- package/workspaces/santa-2025/advanced_optimizer.py +0 -293
- package/workspaces/santa-2025/analysis_summary.txt +0 -69
- package/workspaces/santa-2025/baseline_log.txt +0 -21
- package/workspaces/santa-2025/baseline_solution.py +0 -237
- package/workspaces/santa-2025/baseline_submission.csv +0 -20101
- package/workspaces/santa-2025/competition_data_page.html +0 -131
- package/workspaces/santa-2025/competition_page.html +0 -131
- package/workspaces/santa-2025/create_ensemble.py +0 -160
- package/workspaces/santa-2025/ensemble_submission.csv +0 -20101
- package/workspaces/santa-2025/evaluate_submission.py +0 -173
- package/workspaces/santa-2025/explore_competition.py +0 -62
- package/workspaces/santa-2025/fetch_competition_info.py +0 -57
- package/workspaces/santa-2025/fix_small_configs_fast.py +0 -184
- package/workspaces/santa-2025/improved_log.txt +0 -48
- package/workspaces/santa-2025/improved_solution.py +0 -325
- package/workspaces/santa-2025/improved_submission.csv +0 -20101
- package/workspaces/santa-2025/optimize_small_configs.py +0 -272
- package/workspaces/santa-2025/optimized_n1_to_n6.csv +0 -22
- package/workspaces/santa-2025/optimized_solution.py +0 -393
- package/workspaces/santa-2025/optimized_submission_score70.93.csv +0 -20101
- package/workspaces/santa-2025/puzzle_010.png +0 -0
- package/workspaces/santa-2025/puzzle_020.png +0 -0
- package/workspaces/santa-2025/puzzle_050.png +0 -0
- package/workspaces/santa-2025/puzzle_100.png +0 -0
- package/workspaces/santa-2025/puzzle_150.png +0 -0
- package/workspaces/santa-2025/puzzle_200.png +0 -0
- package/workspaces/santa-2025/requirements.txt +0 -8
- package/workspaces/santa-2025/sample_submission.csv +0 -20101
- package/workspaces/santa-2025/santa-2025-getting-started.ipynb +0 -1
- package/workspaces/santa-2025/santa-2025-getting-started.py +0 -320
- package/workspaces/santa-2025/santa-2025-metric.ipynb +0 -1
- package/workspaces/santa-2025/santa-2025-metric.py +0 -157
- package/workspaces/santa-2025/santa-2025.zip +0 -0
- package/workspaces/santa-2025/test_solution.py +0 -204
- package/workspaces/santa-2025/ultra_optimized_score70.93.csv +0 -20101
- package/workspaces/santa-2025/ultra_optimizer.py +0 -267
- package/workspaces/santa-2025/visualize.py +0 -166
package/src/index.tsx
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Uses Ink (React) for terminal UI.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import React, { useState, useEffect } from "react";
|
|
7
|
+
import React, { useState, useEffect, useRef } from "react";
|
|
8
8
|
import { render, Box, Text, useApp, useInput, useStdin, Static } from "ink";
|
|
9
9
|
import Spinner from "ink-spinner";
|
|
10
10
|
import TextInput from "ink-text-input";
|
|
@@ -14,6 +14,7 @@ import * as path from "path";
|
|
|
14
14
|
import {
|
|
15
15
|
getApiKey,
|
|
16
16
|
getBaseUrl,
|
|
17
|
+
getMleModel,
|
|
17
18
|
saveConfig,
|
|
18
19
|
clearApiKey,
|
|
19
20
|
getHfToken,
|
|
@@ -21,7 +22,7 @@ import {
|
|
|
21
22
|
clearHfToken,
|
|
22
23
|
} from "./config.js";
|
|
23
24
|
import * as api from "./api.js";
|
|
24
|
-
import {
|
|
25
|
+
import { WebSocketClient, type HistoryMessage } from "./client/WebSocketClient.js";
|
|
25
26
|
import {
|
|
26
27
|
isEnabled as isTelemetryEnabled,
|
|
27
28
|
hasChosenTelemetry,
|
|
@@ -78,6 +79,53 @@ function formatJson(data: unknown): string {
|
|
|
78
79
|
return JSON.stringify(filterInternalFields(data), null, 2);
|
|
79
80
|
}
|
|
80
81
|
|
|
82
|
+
function extractDetailMessage(payload: unknown): string | undefined {
|
|
83
|
+
if (payload === null || payload === undefined) return undefined;
|
|
84
|
+
if (typeof payload === "string") return payload;
|
|
85
|
+
|
|
86
|
+
if (Array.isArray(payload)) {
|
|
87
|
+
const parts = payload
|
|
88
|
+
.map((item) => extractDetailMessage(item))
|
|
89
|
+
.filter((item): item is string => Boolean(item && item.trim()));
|
|
90
|
+
return parts.length > 0 ? parts.join("; ") : undefined;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (typeof payload === "object") {
|
|
94
|
+
const record = payload as Record<string, unknown>;
|
|
95
|
+
if (typeof record.detail === "string") return record.detail;
|
|
96
|
+
if (record.detail !== undefined) {
|
|
97
|
+
const detail = extractDetailMessage(record.detail);
|
|
98
|
+
if (detail) return detail;
|
|
99
|
+
}
|
|
100
|
+
if (typeof record.message === "string") return record.message;
|
|
101
|
+
if (typeof record.error === "string") return record.error;
|
|
102
|
+
if (typeof record.msg === "string") return record.msg;
|
|
103
|
+
if (Array.isArray(record.loc) && typeof record.msg === "string") {
|
|
104
|
+
return `${record.loc.join(".")}: ${record.msg}`;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function formatApiError(error: string): string {
|
|
112
|
+
const trimmed = error.trim();
|
|
113
|
+
if (!trimmed) return error;
|
|
114
|
+
|
|
115
|
+
const likelyJson =
|
|
116
|
+
(trimmed.startsWith("{") && trimmed.endsWith("}")) ||
|
|
117
|
+
(trimmed.startsWith("[") && trimmed.endsWith("]"));
|
|
118
|
+
|
|
119
|
+
if (!likelyJson) return error;
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
const parsed = JSON.parse(trimmed) as unknown;
|
|
123
|
+
return extractDetailMessage(parsed) || error;
|
|
124
|
+
} catch {
|
|
125
|
+
return error;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
81
129
|
/**
|
|
82
130
|
* Parse a dataset string in "name[:version]" format into a DatasetRef object.
|
|
83
131
|
* If version is omitted, defaults to "latest".
|
|
@@ -103,9 +151,30 @@ function parseDatasetRef(datasetStr: string): api.DatasetRef | null {
|
|
|
103
151
|
};
|
|
104
152
|
}
|
|
105
153
|
|
|
106
|
-
|
|
154
|
+
const BOOLEAN_FLAGS = new Set([
|
|
155
|
+
"help",
|
|
156
|
+
"h",
|
|
157
|
+
"version",
|
|
158
|
+
"v",
|
|
159
|
+
"private",
|
|
160
|
+
"save",
|
|
161
|
+
"multi-label",
|
|
162
|
+
"include-spans",
|
|
163
|
+
"echo",
|
|
164
|
+
"include-confidence",
|
|
165
|
+
"format-results",
|
|
166
|
+
"reasoning-trace",
|
|
167
|
+
"use-meta-felix",
|
|
168
|
+
]);
|
|
169
|
+
|
|
170
|
+
function parseArgs(argv: string[]): {
|
|
171
|
+
command: string[];
|
|
172
|
+
flags: Record<string, string>;
|
|
173
|
+
parseErrors: string[];
|
|
174
|
+
} {
|
|
107
175
|
const command: string[] = [];
|
|
108
176
|
const flags: Record<string, string> = {};
|
|
177
|
+
const parseErrors: string[] = [];
|
|
109
178
|
|
|
110
179
|
for (let i = 0; i < argv.length; i++) {
|
|
111
180
|
const arg = argv[i];
|
|
@@ -116,7 +185,12 @@ function parseArgs(argv: string[]): { command: string[]; flags: Record<string, s
|
|
|
116
185
|
flags[key] = next;
|
|
117
186
|
i++;
|
|
118
187
|
} else {
|
|
119
|
-
|
|
188
|
+
if (BOOLEAN_FLAGS.has(key)) {
|
|
189
|
+
flags[key] = "true";
|
|
190
|
+
} else {
|
|
191
|
+
parseErrors.push(`--${key}`);
|
|
192
|
+
flags[key] = "";
|
|
193
|
+
}
|
|
120
194
|
}
|
|
121
195
|
} else if (arg.startsWith("-") && arg.length === 2) {
|
|
122
196
|
// Handle short flags like -v, -h
|
|
@@ -126,14 +200,37 @@ function parseArgs(argv: string[]): { command: string[]; flags: Record<string, s
|
|
|
126
200
|
flags[key] = next;
|
|
127
201
|
i++;
|
|
128
202
|
} else {
|
|
129
|
-
|
|
203
|
+
if (BOOLEAN_FLAGS.has(key)) {
|
|
204
|
+
flags[key] = "true";
|
|
205
|
+
} else {
|
|
206
|
+
parseErrors.push(`-${key}`);
|
|
207
|
+
flags[key] = "";
|
|
208
|
+
}
|
|
130
209
|
}
|
|
131
210
|
} else {
|
|
132
211
|
command.push(arg);
|
|
133
212
|
}
|
|
134
213
|
}
|
|
135
214
|
|
|
136
|
-
return { command, flags };
|
|
215
|
+
return { command, flags, parseErrors };
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
type CreateProjectExample = Record<string, unknown> | undefined;
|
|
219
|
+
|
|
220
|
+
function parseProjectExample(exampleStr: string | undefined): { value?: CreateProjectExample; error?: string } {
|
|
221
|
+
if (!exampleStr) {
|
|
222
|
+
return { value: undefined };
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
try {
|
|
226
|
+
const parsed = JSON.parse(exampleStr) as unknown;
|
|
227
|
+
if (!parsed || Array.isArray(parsed) || typeof parsed !== "object") {
|
|
228
|
+
return { error: "--example must be a JSON object" };
|
|
229
|
+
}
|
|
230
|
+
return { value: parsed as CreateProjectExample };
|
|
231
|
+
} catch {
|
|
232
|
+
return { error: "--example must be valid JSON" };
|
|
233
|
+
}
|
|
137
234
|
}
|
|
138
235
|
|
|
139
236
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -151,7 +248,7 @@ const Loading: React.FC<{ message?: string }> = ({ message }) => (
|
|
|
151
248
|
|
|
152
249
|
const ErrorMessage: React.FC<{ error: string }> = ({ error }) => (
|
|
153
250
|
<Box>
|
|
154
|
-
<Text color="red">Error: {error}</Text>
|
|
251
|
+
<Text color="red">Error: {formatApiError(error)}</Text>
|
|
155
252
|
</Box>
|
|
156
253
|
);
|
|
157
254
|
|
|
@@ -470,18 +567,103 @@ const AuthStatus: React.FC = () => {
|
|
|
470
567
|
const { exit } = useApp();
|
|
471
568
|
const apiKey = getApiKey();
|
|
472
569
|
const baseUrl = getBaseUrl();
|
|
570
|
+
const keyFromEnv = Boolean(process.env.PIONEER_API_KEY);
|
|
571
|
+
const [validationState, setValidationState] = useState<
|
|
572
|
+
"no-key" | "checking" | "valid" | "invalid" | "error"
|
|
573
|
+
>(apiKey ? "checking" : "no-key");
|
|
574
|
+
const [validationError, setValidationError] = useState<string | null>(null);
|
|
473
575
|
|
|
474
576
|
useEffect(() => {
|
|
475
|
-
|
|
476
|
-
|
|
577
|
+
let cancelled = false;
|
|
578
|
+
|
|
579
|
+
if (!apiKey) {
|
|
580
|
+
setValidationState("no-key");
|
|
581
|
+
setValidationError(null);
|
|
582
|
+
return () => {
|
|
583
|
+
cancelled = true;
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
setValidationState("checking");
|
|
588
|
+
setValidationError(null);
|
|
589
|
+
|
|
590
|
+
(async () => {
|
|
591
|
+
const result = await api.validateApiKey(apiKey);
|
|
592
|
+
if (cancelled) return;
|
|
593
|
+
|
|
594
|
+
if (result.ok) {
|
|
595
|
+
setValidationState("valid");
|
|
596
|
+
return;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
if (result.status === 401 || result.status === 403) {
|
|
600
|
+
setValidationState("invalid");
|
|
601
|
+
setValidationError(result.error ? formatApiError(result.error) : null);
|
|
602
|
+
return;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
setValidationState("error");
|
|
606
|
+
setValidationError(
|
|
607
|
+
result.error ? formatApiError(result.error) : `HTTP ${result.status}`
|
|
608
|
+
);
|
|
609
|
+
})();
|
|
610
|
+
|
|
611
|
+
return () => {
|
|
612
|
+
cancelled = true;
|
|
613
|
+
};
|
|
614
|
+
}, [apiKey]);
|
|
615
|
+
|
|
616
|
+
useEffect(() => {
|
|
617
|
+
if (validationState === "checking") return;
|
|
618
|
+
const timeout = setTimeout(() => exit(), validationState === "error" ? 2000 : 1200);
|
|
619
|
+
return () => clearTimeout(timeout);
|
|
620
|
+
}, [validationState, exit]);
|
|
477
621
|
|
|
478
622
|
return (
|
|
479
623
|
<Box flexDirection="column">
|
|
480
624
|
<Text>Base URL: {baseUrl}</Text>
|
|
481
625
|
<Text>
|
|
482
|
-
Logged in:{" "}
|
|
626
|
+
Logged in (key configured):{" "}
|
|
483
627
|
<Text color={apiKey ? "green" : "red"}>{apiKey ? "Yes" : "No"}</Text>
|
|
484
628
|
</Text>
|
|
629
|
+
{apiKey && (
|
|
630
|
+
<Text dimColor>
|
|
631
|
+
Key source: {keyFromEnv ? "PIONEER_API_KEY environment variable" : "saved config"}
|
|
632
|
+
</Text>
|
|
633
|
+
)}
|
|
634
|
+
{apiKey && (
|
|
635
|
+
<Text>
|
|
636
|
+
Key valid for current backend:{" "}
|
|
637
|
+
<Text
|
|
638
|
+
color={
|
|
639
|
+
validationState === "valid"
|
|
640
|
+
? "green"
|
|
641
|
+
: validationState === "invalid"
|
|
642
|
+
? "red"
|
|
643
|
+
: validationState === "error"
|
|
644
|
+
? "yellow"
|
|
645
|
+
: "cyan"
|
|
646
|
+
}
|
|
647
|
+
>
|
|
648
|
+
{validationState === "valid"
|
|
649
|
+
? "Yes"
|
|
650
|
+
: validationState === "invalid"
|
|
651
|
+
? "No"
|
|
652
|
+
: validationState === "error"
|
|
653
|
+
? "Unable to verify"
|
|
654
|
+
: "Checking..."}
|
|
655
|
+
</Text>
|
|
656
|
+
</Text>
|
|
657
|
+
)}
|
|
658
|
+
{validationState === "invalid" && (
|
|
659
|
+
<Text dimColor>
|
|
660
|
+
This API key is not valid for this backend. Dev and prod/local keys are different.
|
|
661
|
+
</Text>
|
|
662
|
+
)}
|
|
663
|
+
{validationError && validationState !== "checking" && (
|
|
664
|
+
<Text dimColor>Details: {validationError}</Text>
|
|
665
|
+
)}
|
|
666
|
+
{!apiKey && <Text dimColor>Run 'pioneer auth login' to configure an API key.</Text>}
|
|
485
667
|
</Box>
|
|
486
668
|
);
|
|
487
669
|
};
|
|
@@ -531,133 +713,870 @@ function ApiCommand<T>({ action, successMessage }: ApiCommandProps<T>) {
|
|
|
531
713
|
);
|
|
532
714
|
}
|
|
533
715
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
716
|
+
interface AgentInteractiveCommandProps {
|
|
717
|
+
message: string;
|
|
718
|
+
conversationId?: string;
|
|
719
|
+
history?: api.AgentChatHistoryItem[];
|
|
720
|
+
}
|
|
537
721
|
|
|
538
|
-
function
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
722
|
+
function toHistoryMessages(
|
|
723
|
+
items: Array<api.AgentChatHistoryItem | api.ChatSessionMessage>
|
|
724
|
+
): HistoryMessage[] {
|
|
725
|
+
return items
|
|
726
|
+
.filter((item) => Boolean(item && typeof item.content === "string" && typeof item.role === "string"))
|
|
727
|
+
.map((item) => {
|
|
728
|
+
const message: HistoryMessage = {
|
|
729
|
+
role: item.role as "user" | "assistant" | "tool" | string,
|
|
730
|
+
content: item.content,
|
|
731
|
+
};
|
|
732
|
+
|
|
733
|
+
const sessionMessage = item as api.ChatSessionMessage;
|
|
734
|
+
if (sessionMessage.tool_call_id) {
|
|
735
|
+
message.tool_call_id = sessionMessage.tool_call_id;
|
|
736
|
+
}
|
|
737
|
+
if (sessionMessage.tool_calls && Array.isArray(sessionMessage.tool_calls)) {
|
|
738
|
+
message.tool_calls = sessionMessage.tool_calls.filter((call) => Boolean(call));
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
return message;
|
|
742
|
+
});
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
function AgentInteractiveCommand({ message, conversationId, history }: AgentInteractiveCommandProps) {
|
|
746
|
+
const [state, setState] = useState<"connecting" | "running" | "done" | "error">("connecting");
|
|
747
|
+
const [stream, setStream] = useState("");
|
|
542
748
|
const [error, setError] = useState("");
|
|
749
|
+
const [statusHint, setStatusHint] = useState("");
|
|
750
|
+
const [client] = useState(() => new WebSocketClient());
|
|
751
|
+
const doneHistory = useRef<HistoryMessage[] | undefined>(undefined);
|
|
543
752
|
|
|
544
753
|
useEffect(() => {
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
754
|
+
let isActive = true;
|
|
755
|
+
const model = getMleModel();
|
|
756
|
+
let wsSessionId: string | undefined;
|
|
757
|
+
const finish = (code: number) => {
|
|
758
|
+
setTimeout(() => process.exit(code), 300);
|
|
759
|
+
};
|
|
760
|
+
const getLatestAssistantContent = (
|
|
761
|
+
messages: HistoryMessage[] | undefined
|
|
762
|
+
): string => {
|
|
763
|
+
if (!messages?.length) {
|
|
764
|
+
return "";
|
|
765
|
+
}
|
|
766
|
+
const lastAssistant = [...messages]
|
|
767
|
+
.reverse()
|
|
768
|
+
.find(
|
|
769
|
+
(entry) =>
|
|
770
|
+
entry.role === "assistant" && typeof entry.content === "string" && entry.content.trim()
|
|
771
|
+
);
|
|
772
|
+
return lastAssistant?.content?.trim() ?? "";
|
|
773
|
+
};
|
|
774
|
+
let streamBuffer = "";
|
|
775
|
+
const appendStream = (content: string) => {
|
|
776
|
+
streamBuffer += content;
|
|
777
|
+
setStream(streamBuffer);
|
|
778
|
+
};
|
|
779
|
+
const runAgentFallback = async (
|
|
780
|
+
fallbackHistory: HistoryMessage[],
|
|
781
|
+
sessionIdHint?: string
|
|
782
|
+
) => {
|
|
783
|
+
const plainHistory: api.AgentChatHistoryItem[] = fallbackHistory.map((entry) => ({
|
|
784
|
+
role: entry.role,
|
|
785
|
+
content: entry.content,
|
|
786
|
+
}));
|
|
787
|
+
const fallbackTimeout = (ms: number) =>
|
|
788
|
+
new Promise<never>((_, reject) => {
|
|
789
|
+
setTimeout(() => reject(new Error(`REST fallback timed out after ${ms}ms`)), ms);
|
|
790
|
+
});
|
|
791
|
+
setState("running");
|
|
792
|
+
setStatusHint("WebSocket unavailable, using REST fallback...");
|
|
793
|
+
try {
|
|
794
|
+
const runRequest = (sessionIdOverride?: string) => {
|
|
795
|
+
const requestConversationId = sessionIdOverride;
|
|
796
|
+
return Promise.race([
|
|
797
|
+
api.agentChat({
|
|
798
|
+
message,
|
|
799
|
+
...(requestConversationId ? { conversation_id: requestConversationId } : {}),
|
|
800
|
+
...(plainHistory.length ? { history: plainHistory } : {}),
|
|
801
|
+
}),
|
|
802
|
+
fallbackTimeout(8000),
|
|
803
|
+
]);
|
|
804
|
+
};
|
|
805
|
+
|
|
806
|
+
const attempts = Array.from(
|
|
807
|
+
new Set([sessionIdHint, conversationId, undefined] as Array<string | undefined>)
|
|
808
|
+
);
|
|
809
|
+
let result: Awaited<ReturnType<typeof runRequest>> | undefined;
|
|
810
|
+
let lastError: string | undefined;
|
|
811
|
+
|
|
812
|
+
for (const attemptConversationId of attempts) {
|
|
813
|
+
const attemptResult = await runRequest(attemptConversationId);
|
|
814
|
+
if (attemptResult.ok && attemptResult.data?.answer) {
|
|
815
|
+
result = attemptResult;
|
|
816
|
+
break;
|
|
817
|
+
}
|
|
818
|
+
if (!attemptResult.ok && attemptResult.error) {
|
|
819
|
+
lastError = attemptResult.error;
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
if (!result) {
|
|
824
|
+
if (lastError) {
|
|
825
|
+
throw new Error(lastError || "Agent fallback request failed.");
|
|
826
|
+
}
|
|
827
|
+
result = {
|
|
828
|
+
ok: false,
|
|
829
|
+
status: 0,
|
|
830
|
+
error: "Agent fallback request failed.",
|
|
831
|
+
};
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
if (!isActive) {
|
|
835
|
+
return;
|
|
836
|
+
}
|
|
837
|
+
if (!result.ok) {
|
|
838
|
+
throw new Error(lastError || result.error || "Agent fallback request failed.");
|
|
839
|
+
}
|
|
840
|
+
setStream(result.data?.answer ?? "");
|
|
841
|
+
if (!result.data?.answer) {
|
|
842
|
+
setError("Agent returned no response content.");
|
|
843
|
+
setState("error");
|
|
844
|
+
setTimeout(() => process.exit(1), 300);
|
|
845
|
+
return;
|
|
846
|
+
}
|
|
847
|
+
setStatusHint("");
|
|
549
848
|
setState("done");
|
|
550
|
-
|
|
551
|
-
|
|
849
|
+
setTimeout(() => process.exit(0), 300);
|
|
850
|
+
} catch (fallbackError) {
|
|
851
|
+
if (!isActive) {
|
|
852
|
+
return;
|
|
853
|
+
}
|
|
854
|
+
const fallbackErrorMessage =
|
|
855
|
+
fallbackError instanceof Error
|
|
856
|
+
? fallbackError.message
|
|
857
|
+
: String(fallbackError);
|
|
858
|
+
if (fallbackErrorMessage.includes("REST fallback timed out")) {
|
|
859
|
+
setError(
|
|
860
|
+
"Interactive mode timed out. Agent runtime is not reachable in this environment.\n" +
|
|
861
|
+
"Retry in standard mode (no mode flag needed), or set up a reachable WSS endpoint."
|
|
862
|
+
);
|
|
863
|
+
} else {
|
|
864
|
+
setError(fallbackErrorMessage);
|
|
865
|
+
}
|
|
552
866
|
setState("error");
|
|
867
|
+
setTimeout(() => process.exit(1), 300);
|
|
553
868
|
}
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
869
|
+
};
|
|
870
|
+
const start = async () => {
|
|
871
|
+
doneHistory.current = undefined;
|
|
872
|
+
const mergedHistory: HistoryMessage[] = [];
|
|
873
|
+
let commandCompleted = false;
|
|
874
|
+
let responseTimeoutId: ReturnType<typeof setTimeout> | undefined;
|
|
875
|
+
const fallbackOnTimeout = async () => {
|
|
876
|
+
if (!isActive || commandCompleted) {
|
|
877
|
+
return;
|
|
878
|
+
}
|
|
879
|
+
commandCompleted = true;
|
|
880
|
+
if (responseTimeoutId) {
|
|
881
|
+
clearTimeout(responseTimeoutId);
|
|
882
|
+
}
|
|
883
|
+
client.disconnect();
|
|
884
|
+
await runAgentFallback(mergedHistory, wsSessionId);
|
|
885
|
+
};
|
|
886
|
+
|
|
887
|
+
const connectWithTimeout = async (ms: number): Promise<void> => {
|
|
888
|
+
return new Promise<void>((resolve, reject) => {
|
|
889
|
+
const timeoutId = setTimeout(() => {
|
|
890
|
+
reject(new Error(`WebSocket connect timed out after ${ms}ms`));
|
|
891
|
+
}, ms);
|
|
892
|
+
|
|
893
|
+
client.connect()
|
|
894
|
+
.then(() => {
|
|
895
|
+
clearTimeout(timeoutId);
|
|
896
|
+
resolve();
|
|
897
|
+
})
|
|
898
|
+
.catch((err) => {
|
|
899
|
+
clearTimeout(timeoutId);
|
|
900
|
+
reject(err);
|
|
901
|
+
});
|
|
902
|
+
});
|
|
903
|
+
};
|
|
904
|
+
const withTimeout = async <T,>(promise: Promise<T>, ms: number, label: string): Promise<T> => {
|
|
905
|
+
return new Promise<T>((resolve, reject) => {
|
|
906
|
+
const timeoutId = setTimeout(() => {
|
|
907
|
+
reject(new Error(`${label} timed out after ${ms}ms`));
|
|
908
|
+
}, ms);
|
|
909
|
+
|
|
910
|
+
promise.then(
|
|
911
|
+
(value) => {
|
|
912
|
+
clearTimeout(timeoutId);
|
|
913
|
+
resolve(value);
|
|
914
|
+
},
|
|
915
|
+
(error) => {
|
|
916
|
+
clearTimeout(timeoutId);
|
|
917
|
+
reject(error);
|
|
918
|
+
}
|
|
919
|
+
);
|
|
920
|
+
});
|
|
921
|
+
};
|
|
922
|
+
|
|
923
|
+
try {
|
|
924
|
+
if (conversationId) {
|
|
925
|
+
setStatusHint(`Loading conversation ${conversationId}...`);
|
|
926
|
+
const sessionResult = await api.getAgentSession(conversationId);
|
|
927
|
+
if (!sessionResult.ok) {
|
|
928
|
+
throw new Error(
|
|
929
|
+
sessionResult.error ??
|
|
930
|
+
`Could not load conversation ${conversationId}. Please check the conversation id and credentials.`
|
|
931
|
+
);
|
|
932
|
+
}
|
|
557
933
|
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
934
|
+
const session = sessionResult.data;
|
|
935
|
+
if (session?.messages?.length) {
|
|
936
|
+
mergedHistory.push(...toHistoryMessages(session.messages));
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
if (history?.length) {
|
|
941
|
+
mergedHistory.push(...toHistoryMessages(history));
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
const isWsHealthy = await withTimeout(client.health(), 3000, "WebSocket health check");
|
|
945
|
+
if (!isWsHealthy) {
|
|
946
|
+
throw new Error("WebSocket endpoint is not reachable.");
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
await connectWithTimeout(5000);
|
|
950
|
+
if (!isActive) {
|
|
951
|
+
return;
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
setStatusHint("");
|
|
955
|
+
setState("running");
|
|
956
|
+
responseTimeoutId = setTimeout(() => {
|
|
957
|
+
void fallbackOnTimeout();
|
|
958
|
+
}, 5000);
|
|
959
|
+
|
|
960
|
+
await client.chat(message, {
|
|
961
|
+
onStream: (content) => {
|
|
962
|
+
appendStream(content);
|
|
963
|
+
},
|
|
964
|
+
onAssistantMessage: (content) => {
|
|
965
|
+
appendStream(content);
|
|
966
|
+
},
|
|
967
|
+
onToolCall: async (call) => {
|
|
968
|
+
setStatusHint(`Tool requested: ${call.tool}`);
|
|
969
|
+
return "CLI does not execute tool calls yet.";
|
|
970
|
+
},
|
|
971
|
+
onError: (err) => {
|
|
972
|
+
if (!isActive) return;
|
|
973
|
+
setError(err.message || "WebSocket agent error");
|
|
974
|
+
setState("error");
|
|
975
|
+
finish(1);
|
|
976
|
+
},
|
|
977
|
+
onDone: (messages, sessionId) => {
|
|
978
|
+
if (!isActive) return;
|
|
979
|
+
commandCompleted = true;
|
|
980
|
+
if (responseTimeoutId) {
|
|
981
|
+
clearTimeout(responseTimeoutId);
|
|
982
|
+
}
|
|
983
|
+
doneHistory.current = messages;
|
|
984
|
+
wsSessionId = sessionId;
|
|
985
|
+
},
|
|
986
|
+
}, {
|
|
987
|
+
history: mergedHistory,
|
|
988
|
+
...(model ? { config: { model } } : {}),
|
|
989
|
+
fileReferences: [],
|
|
990
|
+
});
|
|
991
|
+
if (!streamBuffer.trim()) {
|
|
992
|
+
const doneAssistantContent = getLatestAssistantContent(doneHistory.current);
|
|
993
|
+
if (doneAssistantContent) {
|
|
994
|
+
appendStream(doneAssistantContent);
|
|
995
|
+
setState("done");
|
|
996
|
+
finish(0);
|
|
997
|
+
return;
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
setStatusHint("No assistant content in websocket response; retrying via REST fallback.");
|
|
1001
|
+
await runAgentFallback(mergedHistory, wsSessionId);
|
|
1002
|
+
return;
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
setState("done");
|
|
1006
|
+
finish(0);
|
|
1007
|
+
} catch (err) {
|
|
1008
|
+
if (!isActive) return;
|
|
1009
|
+
commandCompleted = true;
|
|
1010
|
+
if (responseTimeoutId) {
|
|
1011
|
+
clearTimeout(responseTimeoutId);
|
|
1012
|
+
}
|
|
1013
|
+
const rawError = err instanceof Error ? err.message : String(err);
|
|
1014
|
+
const unavailable =
|
|
1015
|
+
rawError.includes("WebSocket") ||
|
|
1016
|
+
rawError.includes("websocket") ||
|
|
1017
|
+
rawError.includes("timed out") ||
|
|
1018
|
+
rawError.includes("not reachable");
|
|
1019
|
+
|
|
1020
|
+
if (unavailable) {
|
|
1021
|
+
const wsUrl = client.getWebSocketUrl();
|
|
1022
|
+
setStatusHint(`WebSocket timed out at ${wsUrl}. Falling back to REST.`);
|
|
1023
|
+
await runAgentFallback(mergedHistory);
|
|
1024
|
+
return;
|
|
1025
|
+
}
|
|
1026
|
+
setError(
|
|
1027
|
+
rawError || "Agent runtime unavailable. Retry by running `agent` in standard mode (omit --mode)."
|
|
1028
|
+
);
|
|
1029
|
+
setState("error");
|
|
1030
|
+
finish(1);
|
|
1031
|
+
}
|
|
1032
|
+
};
|
|
1033
|
+
start();
|
|
1034
|
+
|
|
1035
|
+
return () => {
|
|
1036
|
+
isActive = false;
|
|
1037
|
+
if (state !== "done" && state !== "error") {
|
|
1038
|
+
client.disconnect();
|
|
1039
|
+
}
|
|
1040
|
+
};
|
|
1041
|
+
}, [client, conversationId, history, message]);
|
|
1042
|
+
|
|
1043
|
+
useEffect(() => {
|
|
1044
|
+
if (state === "done") {
|
|
1045
|
+
setTimeout(() => process.exit(0), 300);
|
|
1046
|
+
} else if (state === "error") {
|
|
1047
|
+
setTimeout(() => process.exit(1), 300);
|
|
1048
|
+
}
|
|
1049
|
+
}, [state]);
|
|
561
1050
|
|
|
562
1051
|
if (state === "error") {
|
|
563
|
-
return
|
|
1052
|
+
return (
|
|
1053
|
+
<Box flexDirection="column">
|
|
1054
|
+
<ErrorMessage error={error || "WebSocket agent command failed."} />
|
|
1055
|
+
</Box>
|
|
1056
|
+
);
|
|
564
1057
|
}
|
|
565
1058
|
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
1059
|
+
if (state === "connecting") {
|
|
1060
|
+
return (
|
|
1061
|
+
<Box flexDirection="column">
|
|
1062
|
+
<Loading message={statusHint || "Connecting to agent runtime..."} />
|
|
1063
|
+
</Box>
|
|
1064
|
+
);
|
|
1065
|
+
}
|
|
570
1066
|
|
|
571
1067
|
return (
|
|
572
1068
|
<Box flexDirection="column">
|
|
573
|
-
{
|
|
574
|
-
<
|
|
1069
|
+
{state === "running" ? (
|
|
1070
|
+
<Loading message={stream ? "Streaming response..." : "Waiting for agent response..."} />
|
|
575
1071
|
) : (
|
|
576
|
-
|
|
577
|
-
<Text key={log.id} color={log.level === "ERROR" ? "red" : log.level === "WARNING" ? "yellow" : undefined}>
|
|
578
|
-
{formatLogEntry(log)}
|
|
579
|
-
</Text>
|
|
580
|
-
))
|
|
1072
|
+
<Success message="Agent response received" />
|
|
581
1073
|
)}
|
|
1074
|
+
{stream ? <Text>{stream}</Text> : <Text dimColor>No response content yet.</Text>}
|
|
1075
|
+
{conversationId ? <Text dimColor>Conversation: {conversationId}</Text> : null}
|
|
582
1076
|
</Box>
|
|
583
1077
|
);
|
|
584
1078
|
}
|
|
585
1079
|
|
|
586
|
-
|
|
587
|
-
// Local Dataset Helpers
|
|
588
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
589
|
-
|
|
590
|
-
const DATASETS_DIR = path.join(process.cwd(), "datasets");
|
|
1080
|
+
type AutoAgentTurnRole = "user" | "assistant";
|
|
591
1081
|
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
}
|
|
1082
|
+
interface AutoAgentTurn {
|
|
1083
|
+
role: AutoAgentTurnRole;
|
|
1084
|
+
content: string;
|
|
596
1085
|
}
|
|
597
1086
|
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
path: string;
|
|
602
|
-
type: string;
|
|
603
|
-
size: number;
|
|
604
|
-
sample_size: number;
|
|
605
|
-
created_at: string;
|
|
606
|
-
source: "local";
|
|
1087
|
+
function formatAutoAgentTurn(turn: AutoAgentTurn): string {
|
|
1088
|
+
const prefix = turn.role === "user" ? "You: " : "Agent: ";
|
|
1089
|
+
return `${prefix}${turn.content}`;
|
|
607
1090
|
}
|
|
608
1091
|
|
|
609
|
-
function
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
1092
|
+
function AutoAgentInteractiveSession({
|
|
1093
|
+
conversationId: initialConversationId,
|
|
1094
|
+
history,
|
|
1095
|
+
mode,
|
|
1096
|
+
firstMessage,
|
|
1097
|
+
}: {
|
|
1098
|
+
conversationId?: string;
|
|
1099
|
+
history?: api.AgentChatHistoryItem[];
|
|
1100
|
+
mode: "standard" | "research";
|
|
1101
|
+
firstMessage?: string;
|
|
1102
|
+
}) {
|
|
1103
|
+
const [input, setInput] = useState("");
|
|
1104
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
1105
|
+
const [error, setError] = useState("");
|
|
1106
|
+
const [statusHint, setStatusHint] = useState("Start typing...");
|
|
1107
|
+
const [conversationId, setConversationId] = useState(initialConversationId);
|
|
1108
|
+
const [historyState, setHistoryState] = useState<api.AgentChatHistoryItem[]>(history ?? []);
|
|
1109
|
+
const [turns, setTurns] = useState<AutoAgentTurn[]>(
|
|
1110
|
+
(history ?? []).map((entry) =>
|
|
1111
|
+
entry.role === "assistant"
|
|
1112
|
+
? { role: "assistant", content: entry.content }
|
|
1113
|
+
: { role: "user", content: entry.content }
|
|
1114
|
+
)
|
|
1115
|
+
);
|
|
1116
|
+
const didSeedFirstMessage = useRef(false);
|
|
613
1117
|
|
|
614
|
-
const
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
let type = "unknown";
|
|
1118
|
+
const runAutoTurn = async (rawMessage: string) => {
|
|
1119
|
+
const trimmed = rawMessage.trim();
|
|
1120
|
+
if (!trimmed || isLoading) {
|
|
1121
|
+
return;
|
|
1122
|
+
}
|
|
620
1123
|
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
1124
|
+
const nextHistory: api.AgentChatHistoryItem[] = [
|
|
1125
|
+
...historyState,
|
|
1126
|
+
{ role: "user", content: trimmed },
|
|
1127
|
+
];
|
|
1128
|
+
setHistoryState(nextHistory);
|
|
1129
|
+
setTurns((current) => [...current, { role: "user", content: trimmed }]);
|
|
1130
|
+
setInput("");
|
|
1131
|
+
setError("");
|
|
1132
|
+
setIsLoading(true);
|
|
1133
|
+
setStatusHint("Thinking...");
|
|
1134
|
+
|
|
1135
|
+
const result = await api.agentChat({
|
|
1136
|
+
message: trimmed,
|
|
1137
|
+
...(conversationId ? { conversation_id: conversationId } : {}),
|
|
1138
|
+
...(nextHistory.length ? { history: nextHistory } : {}),
|
|
1139
|
+
});
|
|
1140
|
+
|
|
1141
|
+
if (!result.ok) {
|
|
1142
|
+
if (
|
|
1143
|
+
result.status === 403 &&
|
|
1144
|
+
(result.error ?? "").toLowerCase().includes("deep research mode")
|
|
1145
|
+
) {
|
|
1146
|
+
setError(
|
|
1147
|
+
"Research mode requires a Pro subscription.\n" +
|
|
1148
|
+
"To run this command, upgrade your account to Pro and retry.\n" +
|
|
1149
|
+
"Go to Manage subscription under Billing at https://agent.pioneer.ai/account."
|
|
1150
|
+
);
|
|
1151
|
+
} else {
|
|
1152
|
+
setError(result.error || "Agent request failed.");
|
|
1153
|
+
}
|
|
1154
|
+
setIsLoading(false);
|
|
1155
|
+
setStatusHint("Ready for next message.");
|
|
1156
|
+
return;
|
|
628
1157
|
}
|
|
629
1158
|
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
name: filename.replace(".json", ""),
|
|
633
|
-
path: filePath,
|
|
634
|
-
type,
|
|
635
|
-
size: stats.size,
|
|
636
|
-
sample_size: data.length,
|
|
637
|
-
created_at: stats.birthtime.toISOString(),
|
|
638
|
-
source: "local" as const,
|
|
639
|
-
};
|
|
640
|
-
});
|
|
641
|
-
}
|
|
1159
|
+
const answer = result.data.answer?.trim() || "No response content yet.";
|
|
1160
|
+
const nextConversationId = result.data.conversation_id || conversationId;
|
|
642
1161
|
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
}
|
|
1162
|
+
setConversationId(nextConversationId);
|
|
1163
|
+
setTurns((current) => [...current, { role: "assistant", content: answer }]);
|
|
1164
|
+
setHistoryState((current) => [...current, { role: "assistant", content: answer }]);
|
|
1165
|
+
setStatusHint("Ready for next message.");
|
|
1166
|
+
setIsLoading(false);
|
|
1167
|
+
};
|
|
650
1168
|
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
1169
|
+
useEffect(() => {
|
|
1170
|
+
if (!firstMessage || didSeedFirstMessage.current) {
|
|
1171
|
+
return;
|
|
1172
|
+
}
|
|
654
1173
|
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
1174
|
+
didSeedFirstMessage.current = true;
|
|
1175
|
+
void runAutoTurn(firstMessage);
|
|
1176
|
+
}, [firstMessage]);
|
|
1177
|
+
|
|
1178
|
+
return (
|
|
1179
|
+
<Box flexDirection="column">
|
|
1180
|
+
<Text bold>Agent mode selected.</Text>
|
|
1181
|
+
<Text>
|
|
1182
|
+
Mode: {mode === "research" ? "research" : "standard"}{" "}
|
|
1183
|
+
{conversationId ? `(conversation ${conversationId})` : "(new conversation)"}
|
|
1184
|
+
</Text>
|
|
1185
|
+
<Box flexDirection="column" marginTop={1}>
|
|
1186
|
+
{turns.map((entry, idx) => (
|
|
1187
|
+
<Text key={`agent-turn-${idx}`} dimColor={entry.role === "user"}>
|
|
1188
|
+
{formatAutoAgentTurn(entry)}
|
|
1189
|
+
</Text>
|
|
1190
|
+
))}
|
|
1191
|
+
</Box>
|
|
1192
|
+
<Box marginTop={1}>
|
|
1193
|
+
{isLoading ? <Loading message={statusHint} /> : <Text color="cyan">> </Text>}
|
|
1194
|
+
{isLoading ? null : (
|
|
1195
|
+
<TextInput
|
|
1196
|
+
value={input}
|
|
1197
|
+
onChange={setInput}
|
|
1198
|
+
onSubmit={runAutoTurn}
|
|
1199
|
+
/>
|
|
1200
|
+
)}
|
|
1201
|
+
</Box>
|
|
1202
|
+
{error && (
|
|
1203
|
+
<Box marginTop={1}>
|
|
1204
|
+
<ErrorMessage error={error} />
|
|
1205
|
+
</Box>
|
|
1206
|
+
)}
|
|
1207
|
+
<Text dimColor>Type Ctrl+C to exit.</Text>
|
|
1208
|
+
</Box>
|
|
1209
|
+
);
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
function AgentInteractivePrompt({
|
|
1213
|
+
conversationId,
|
|
1214
|
+
history,
|
|
1215
|
+
mode,
|
|
1216
|
+
}: {
|
|
1217
|
+
conversationId?: string;
|
|
1218
|
+
history?: api.AgentChatHistoryItem[];
|
|
1219
|
+
mode?: "standard" | "research";
|
|
1220
|
+
}) {
|
|
1221
|
+
const [input, setInput] = useState("");
|
|
1222
|
+
const [isReady, setReady] = useState(false);
|
|
1223
|
+
const [message, setMessage] = useState("");
|
|
1224
|
+
const { isRawModeSupported } = useStdin();
|
|
1225
|
+
const shouldExitImmediately = !isRawModeSupported;
|
|
1226
|
+
|
|
1227
|
+
useEffect(() => {
|
|
1228
|
+
if (!shouldExitImmediately) {
|
|
1229
|
+
return;
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
const timeout = setTimeout(() => {
|
|
1233
|
+
process.exit(0);
|
|
1234
|
+
}, 75);
|
|
1235
|
+
|
|
1236
|
+
return () => clearTimeout(timeout);
|
|
1237
|
+
}, [shouldExitImmediately]);
|
|
1238
|
+
|
|
1239
|
+
if (!isRawModeSupported) {
|
|
1240
|
+
return (
|
|
1241
|
+
<Box flexDirection="column">
|
|
1242
|
+
<ErrorMessage error="Interactive input is not supported in this terminal." />
|
|
1243
|
+
<Text>Use interactive mode for this environment:</Text>
|
|
1244
|
+
<Text dimColor>{` agent${mode === "research" ? " --mode research" : ""}`}</Text>
|
|
1245
|
+
<Text dimColor> agent --help</Text>
|
|
1246
|
+
</Box>
|
|
1247
|
+
);
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
if (!isReady) {
|
|
1251
|
+
return (
|
|
1252
|
+
<Box flexDirection="column">
|
|
1253
|
+
<Text bold>Agent mode selected.</Text>
|
|
1254
|
+
<Text>Type your message and press enter to start:</Text>
|
|
1255
|
+
<Box>
|
|
1256
|
+
<Text color="cyan">> </Text>
|
|
1257
|
+
<TextInput
|
|
1258
|
+
value={input}
|
|
1259
|
+
onChange={setInput}
|
|
1260
|
+
onSubmit={(value) => {
|
|
1261
|
+
const trimmed = value.trim();
|
|
1262
|
+
if (!trimmed) {
|
|
1263
|
+
return;
|
|
1264
|
+
}
|
|
1265
|
+
setMessage(trimmed);
|
|
1266
|
+
setReady(true);
|
|
1267
|
+
}}
|
|
1268
|
+
/>
|
|
1269
|
+
</Box>
|
|
1270
|
+
<Text dimColor>Type Ctrl+C to cancel.</Text>
|
|
1271
|
+
</Box>
|
|
1272
|
+
);
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
return (
|
|
1276
|
+
<AutoAgentInteractiveSession
|
|
1277
|
+
conversationId={conversationId}
|
|
1278
|
+
history={history}
|
|
1279
|
+
mode={mode === "research" ? "research" : "standard"}
|
|
1280
|
+
firstMessage={message}
|
|
1281
|
+
/>
|
|
1282
|
+
);
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
1286
|
+
// Interactive Model Create Selector
|
|
1287
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
1288
|
+
|
|
1289
|
+
function ModelCreateInteractive({
|
|
1290
|
+
name,
|
|
1291
|
+
icon,
|
|
1292
|
+
repo,
|
|
1293
|
+
description,
|
|
1294
|
+
example,
|
|
1295
|
+
}: {
|
|
1296
|
+
name?: string;
|
|
1297
|
+
icon?: string;
|
|
1298
|
+
repo?: string;
|
|
1299
|
+
description?: string;
|
|
1300
|
+
example?: CreateProjectExample;
|
|
1301
|
+
}) {
|
|
1302
|
+
const [query, setQuery] = useState("");
|
|
1303
|
+
const [models, setModels] = useState<api.BaseModelInfo[]>([]);
|
|
1304
|
+
const [loading, setLoading] = useState(true);
|
|
1305
|
+
const [error, setError] = useState("");
|
|
1306
|
+
const [selectedModelId, setSelectedModelId] = useState<string | null>(null);
|
|
1307
|
+
const [highlightIndex, setHighlightIndex] = useState(0);
|
|
1308
|
+
|
|
1309
|
+
useEffect(() => {
|
|
1310
|
+
(async () => {
|
|
1311
|
+
const result = await api.listBaseModels();
|
|
1312
|
+
if (!result.ok) {
|
|
1313
|
+
setError(result.error ?? "Unable to load base models.");
|
|
1314
|
+
setLoading(false);
|
|
1315
|
+
return;
|
|
1316
|
+
}
|
|
1317
|
+
const modelsData = result.data
|
|
1318
|
+
? Array.isArray((result.data as api.BaseModelsResponse).models)
|
|
1319
|
+
? (result.data as api.BaseModelsResponse).models
|
|
1320
|
+
: (result.data as api.BaseModelInfo[])
|
|
1321
|
+
: [];
|
|
1322
|
+
setModels(modelsData.sort((a, b) => a.id.localeCompare(b.id)));
|
|
1323
|
+
setLoading(false);
|
|
1324
|
+
})();
|
|
1325
|
+
}, []);
|
|
1326
|
+
|
|
1327
|
+
const normalizedQuery = query.trim().toLowerCase();
|
|
1328
|
+
const matchingModels = models.filter((model) => {
|
|
1329
|
+
const text = `${model.id} ${model.name ?? ""} ${model.label ?? ""} ${model.description ?? ""}`.toLowerCase();
|
|
1330
|
+
return normalizedQuery.length === 0 || text.includes(normalizedQuery);
|
|
1331
|
+
});
|
|
1332
|
+
const topMatches = matchingModels;
|
|
1333
|
+
useEffect(() => {
|
|
1334
|
+
setHighlightIndex(0);
|
|
1335
|
+
}, [query]);
|
|
1336
|
+
|
|
1337
|
+
const resolveModelId = (queryValue: string): string | undefined => {
|
|
1338
|
+
const trimmed = queryValue.trim();
|
|
1339
|
+
if (!trimmed) {
|
|
1340
|
+
return topMatches[highlightIndex]?.id;
|
|
1341
|
+
}
|
|
1342
|
+
const exact = models.find(
|
|
1343
|
+
(model) => model.id.toLowerCase() === trimmed.toLowerCase()
|
|
1344
|
+
);
|
|
1345
|
+
if (exact) return exact.id;
|
|
1346
|
+
return topMatches[highlightIndex]?.id;
|
|
1347
|
+
};
|
|
1348
|
+
|
|
1349
|
+
useEffect(() => {
|
|
1350
|
+
if (highlightIndex >= topMatches.length) {
|
|
1351
|
+
setHighlightIndex(topMatches.length > 0 ? topMatches.length - 1 : 0);
|
|
1352
|
+
}
|
|
1353
|
+
}, [highlightIndex, topMatches.length]);
|
|
1354
|
+
|
|
1355
|
+
useInput((_, key) => {
|
|
1356
|
+
if (!topMatches.length) return;
|
|
1357
|
+
if (key.upArrow) {
|
|
1358
|
+
setHighlightIndex((idx) => (idx === 0 ? topMatches.length - 1 : idx - 1));
|
|
1359
|
+
return;
|
|
1360
|
+
}
|
|
1361
|
+
if (key.downArrow) {
|
|
1362
|
+
setHighlightIndex((idx) => (idx === topMatches.length - 1 ? 0 : idx + 1));
|
|
1363
|
+
return;
|
|
1364
|
+
}
|
|
1365
|
+
if (key.return) {
|
|
1366
|
+
const resolvedModel = resolveModelId(query);
|
|
1367
|
+
if (!resolvedModel) {
|
|
1368
|
+
setError("No matching models found. Refine your search and try again.");
|
|
1369
|
+
return;
|
|
1370
|
+
}
|
|
1371
|
+
setSelectedModelId(resolvedModel);
|
|
1372
|
+
}
|
|
1373
|
+
});
|
|
1374
|
+
|
|
1375
|
+
if (error) {
|
|
1376
|
+
return (
|
|
1377
|
+
<Box flexDirection="column">
|
|
1378
|
+
<ErrorMessage error={error} />
|
|
1379
|
+
<Text> </Text>
|
|
1380
|
+
<Text dimColor>Try again with --model explicitly, or check your API connectivity.</Text>
|
|
1381
|
+
</Box>
|
|
1382
|
+
);
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
if (selectedModelId) {
|
|
1386
|
+
return (
|
|
1387
|
+
<ApiCommand
|
|
1388
|
+
action={() =>
|
|
1389
|
+
api.createProject({
|
|
1390
|
+
name: name ?? selectedModelId,
|
|
1391
|
+
...(icon ? { icon } : {}),
|
|
1392
|
+
...(repo ? { repo } : {}),
|
|
1393
|
+
...(description ? { description } : {}),
|
|
1394
|
+
active_model_id: selectedModelId,
|
|
1395
|
+
selected_model_id: selectedModelId,
|
|
1396
|
+
...(example ? { example } : {}),
|
|
1397
|
+
})
|
|
1398
|
+
}
|
|
1399
|
+
successMessage="Model entry created"
|
|
1400
|
+
/>
|
|
1401
|
+
);
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
if (loading) {
|
|
1405
|
+
return <Loading message="Loading supported models..." />;
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
return (
|
|
1409
|
+
<Box flexDirection="column">
|
|
1410
|
+
<Text bold>Choose a base model for this entry</Text>
|
|
1411
|
+
<Text>Type to filter. Use ↑/↓ to navigate and Enter to select.</Text>
|
|
1412
|
+
<Text dimColor>Type any part of model id, name, label, or description.</Text>
|
|
1413
|
+
<Text> </Text>
|
|
1414
|
+
<TextInput
|
|
1415
|
+
value={query}
|
|
1416
|
+
onChange={(value) => setQuery(value)}
|
|
1417
|
+
onSubmit={(value) => {
|
|
1418
|
+
const resolvedModel = resolveModelId(value);
|
|
1419
|
+
if (!resolvedModel) {
|
|
1420
|
+
setError("No matching models found. Refine your search and try again.");
|
|
1421
|
+
return;
|
|
1422
|
+
}
|
|
1423
|
+
setSelectedModelId(resolvedModel);
|
|
1424
|
+
}}
|
|
1425
|
+
placeholder="e.g. qwen/qwen3-8b"
|
|
1426
|
+
/>
|
|
1427
|
+
<Text> </Text>
|
|
1428
|
+
{topMatches.length === 0 ? (
|
|
1429
|
+
<Text dimColor>No matching models found.</Text>
|
|
1430
|
+
) : (
|
|
1431
|
+
<Box flexDirection="column">
|
|
1432
|
+
{topMatches.map((model, index) => {
|
|
1433
|
+
const suffix = [model.label, model.task_type, model.type].filter(Boolean).join(" · ");
|
|
1434
|
+
const modelLine = `${model.id}${suffix ? ` (${suffix})` : ""}`;
|
|
1435
|
+
const isHighlighted = index === highlightIndex;
|
|
1436
|
+
return (
|
|
1437
|
+
<Text key={model.id} color={isHighlighted ? "cyan" : undefined} bold={isHighlighted}>
|
|
1438
|
+
{isHighlighted ? "▶ " : " "}
|
|
1439
|
+
{modelLine}
|
|
1440
|
+
</Text>
|
|
1441
|
+
);
|
|
1442
|
+
})}
|
|
1443
|
+
</Box>
|
|
1444
|
+
)}
|
|
1445
|
+
<Text> </Text>
|
|
1446
|
+
<Text dimColor>Press Enter to select the highlighted model.</Text>
|
|
1447
|
+
<Text dimColor> </Text>
|
|
1448
|
+
<Text dimColor>Tip: You can still run {"model endpoints create --model \"<base-model-id>\""} for exact model ids.</Text>
|
|
1449
|
+
</Box>
|
|
1450
|
+
);
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
1454
|
+
// Job Logs Command (prettified output)
|
|
1455
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
1456
|
+
|
|
1457
|
+
function JobLogsCommand({ jobId }: { jobId: string }) {
|
|
1458
|
+
const { exit } = useApp();
|
|
1459
|
+
const [state, setState] = useState<"loading" | "done" | "error">("loading");
|
|
1460
|
+
const [logs, setLogs] = useState<api.TrainingLog[]>([]);
|
|
1461
|
+
const [error, setError] = useState("");
|
|
1462
|
+
|
|
1463
|
+
useEffect(() => {
|
|
1464
|
+
(async () => {
|
|
1465
|
+
const result = await api.getJobLogs(jobId);
|
|
1466
|
+
if (result.ok && result.data) {
|
|
1467
|
+
setLogs(result.data.logs || []);
|
|
1468
|
+
setState("done");
|
|
1469
|
+
} else {
|
|
1470
|
+
setError(result.error ?? "Unknown error");
|
|
1471
|
+
setState("error");
|
|
1472
|
+
}
|
|
1473
|
+
setTimeout(() => exit(), 500);
|
|
1474
|
+
})();
|
|
1475
|
+
}, [jobId, exit]);
|
|
1476
|
+
|
|
1477
|
+
if (state === "loading") {
|
|
1478
|
+
return <Loading />;
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
if (state === "error") {
|
|
1482
|
+
return <ErrorMessage error={error} />;
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1485
|
+
const formatLogEntry = (log: api.TrainingLog): string => {
|
|
1486
|
+
const ts = new Date(log.timestamp).toLocaleTimeString();
|
|
1487
|
+
return `[${ts}] [${log.level}] ${log.message}`;
|
|
1488
|
+
};
|
|
1489
|
+
|
|
1490
|
+
return (
|
|
1491
|
+
<Box flexDirection="column">
|
|
1492
|
+
{logs.length === 0 ? (
|
|
1493
|
+
<Text dimColor>No logs available</Text>
|
|
1494
|
+
) : (
|
|
1495
|
+
logs.map((log) => (
|
|
1496
|
+
<Text key={log.id} color={log.level === "ERROR" ? "red" : log.level === "WARNING" ? "yellow" : undefined}>
|
|
1497
|
+
{formatLogEntry(log)}
|
|
1498
|
+
</Text>
|
|
1499
|
+
))
|
|
1500
|
+
)}
|
|
1501
|
+
</Box>
|
|
1502
|
+
);
|
|
1503
|
+
}
|
|
1504
|
+
|
|
1505
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
1506
|
+
// Local Dataset Helpers
|
|
1507
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
1508
|
+
|
|
1509
|
+
const DATASETS_DIR = path.join(process.cwd(), "datasets");
|
|
1510
|
+
|
|
1511
|
+
function ensureDatasetsDir(): void {
|
|
1512
|
+
if (!fs.existsSync(DATASETS_DIR)) {
|
|
1513
|
+
fs.mkdirSync(DATASETS_DIR, { recursive: true });
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
interface LocalDataset {
|
|
1518
|
+
id: string;
|
|
1519
|
+
name: string;
|
|
1520
|
+
path: string;
|
|
1521
|
+
type: string;
|
|
1522
|
+
size: number;
|
|
1523
|
+
sample_size: number;
|
|
1524
|
+
created_at: string;
|
|
1525
|
+
source: "local";
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
function listLocalDatasets(): LocalDataset[] {
|
|
1529
|
+
if (!fs.existsSync(DATASETS_DIR)) {
|
|
1530
|
+
return [];
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
const files = fs.readdirSync(DATASETS_DIR).filter((f) => f.endsWith(".json"));
|
|
1534
|
+
return files.map((filename) => {
|
|
1535
|
+
const filePath = path.join(DATASETS_DIR, filename);
|
|
1536
|
+
const stats = fs.statSync(filePath);
|
|
1537
|
+
let data: unknown[] = [];
|
|
1538
|
+
let type = "unknown";
|
|
1539
|
+
|
|
1540
|
+
try {
|
|
1541
|
+
const content = JSON.parse(fs.readFileSync(filePath, "utf-8"));
|
|
1542
|
+
data = Array.isArray(content) ? content : content.data ?? [];
|
|
1543
|
+
const firstItem = data[0] as Record<string, unknown> | undefined;
|
|
1544
|
+
type = content.task_type ?? (firstItem?.spans ? "ner" : firstItem?.label ? "classification" : "custom");
|
|
1545
|
+
} catch {
|
|
1546
|
+
// Ignore parse errors
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
return {
|
|
1550
|
+
id: filename.replace(".json", ""),
|
|
1551
|
+
name: filename.replace(".json", ""),
|
|
1552
|
+
path: filePath,
|
|
1553
|
+
type,
|
|
1554
|
+
size: stats.size,
|
|
1555
|
+
sample_size: data.length,
|
|
1556
|
+
created_at: stats.birthtime.toISOString(),
|
|
1557
|
+
source: "local" as const,
|
|
1558
|
+
};
|
|
1559
|
+
});
|
|
1560
|
+
}
|
|
1561
|
+
|
|
1562
|
+
function saveLocalDataset(name: string, data: unknown, type: string): string {
|
|
1563
|
+
ensureDatasetsDir();
|
|
1564
|
+
const filename = `${name.replace(/[^a-zA-Z0-9-_]/g, "_")}.json`;
|
|
1565
|
+
const filePath = path.join(DATASETS_DIR, filename);
|
|
1566
|
+
fs.writeFileSync(filePath, JSON.stringify({ task_type: type, data }, null, 2));
|
|
1567
|
+
return filePath;
|
|
1568
|
+
}
|
|
1569
|
+
|
|
1570
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
1571
|
+
// Generate Command (saves to local file when --save is false)
|
|
1572
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
1573
|
+
|
|
1574
|
+
interface GenerateCommandProps<T> {
|
|
1575
|
+
action: () => Promise<api.ApiResult<T>>;
|
|
1576
|
+
datasetName: string;
|
|
1577
|
+
datasetType: string;
|
|
1578
|
+
saveToRemote: boolean;
|
|
1579
|
+
}
|
|
661
1580
|
|
|
662
1581
|
interface GenerateResult {
|
|
663
1582
|
data?: unknown[];
|
|
@@ -823,173 +1742,15 @@ function DatasetListCommand() {
|
|
|
823
1742
|
}
|
|
824
1743
|
|
|
825
1744
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
826
|
-
//
|
|
1745
|
+
// Job Create Command (with auto-upload for local datasets)
|
|
827
1746
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
828
1747
|
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
useEffect(() => {
|
|
836
|
-
(async () => {
|
|
837
|
-
const result = await api.listCompetitions();
|
|
838
|
-
if (result.ok && result.data) {
|
|
839
|
-
setCompetitions(result.data.competitions || []);
|
|
840
|
-
setState("done");
|
|
841
|
-
} else {
|
|
842
|
-
setError(result.error ?? "Unknown error");
|
|
843
|
-
setState("error");
|
|
844
|
-
}
|
|
845
|
-
setTimeout(() => exit(), 500);
|
|
846
|
-
})();
|
|
847
|
-
}, [exit]);
|
|
848
|
-
|
|
849
|
-
if (state === "loading") {
|
|
850
|
-
return <Loading message="Loading competitions..." />;
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
if (state === "error") {
|
|
854
|
-
return <ErrorMessage error={error} />;
|
|
855
|
-
}
|
|
856
|
-
|
|
857
|
-
if (competitions.length === 0) {
|
|
858
|
-
return <Text dimColor>No active competitions found.</Text>;
|
|
859
|
-
}
|
|
860
|
-
|
|
861
|
-
return (
|
|
862
|
-
<Box flexDirection="column">
|
|
863
|
-
<Text bold color="cyan">Active Competitions ({competitions.length})</Text>
|
|
864
|
-
<Text> </Text>
|
|
865
|
-
{competitions.map((comp, idx) => (
|
|
866
|
-
<Box key={comp.dataset_id} flexDirection="column" marginBottom={1}>
|
|
867
|
-
<Text bold color="yellow">
|
|
868
|
-
{idx + 1}. {comp.dataset_name}
|
|
869
|
-
</Text>
|
|
870
|
-
<Text>
|
|
871
|
-
{" "}Type: <Text color="magenta">{comp.dataset_type}</Text>
|
|
872
|
-
{" "}Samples: <Text color="blue">{comp.sample_count ?? "N/A"}</Text>
|
|
873
|
-
{" "}Entries: <Text color="green">{comp.total_entries}</Text>
|
|
874
|
-
</Text>
|
|
875
|
-
{comp.description && (
|
|
876
|
-
<Text dimColor>{" "}{comp.description}</Text>
|
|
877
|
-
)}
|
|
878
|
-
{comp.labels && comp.labels.length > 0 && (
|
|
879
|
-
<Text>{" "}Labels: <Text color="cyan">{comp.labels.join(", ")}</Text></Text>
|
|
880
|
-
)}
|
|
881
|
-
{comp.winner && (
|
|
882
|
-
<Text>
|
|
883
|
-
{" "}Winner: <Text color="green" bold>{comp.winner.display_name}</Text>
|
|
884
|
-
{" "}(F1: <Text color="yellow">{comp.winner.f1_score.toFixed(4)}</Text>)
|
|
885
|
-
</Text>
|
|
886
|
-
)}
|
|
887
|
-
<Text dimColor>{" "}ID: {comp.dataset_id}</Text>
|
|
888
|
-
</Box>
|
|
889
|
-
))}
|
|
890
|
-
</Box>
|
|
891
|
-
);
|
|
892
|
-
}
|
|
893
|
-
|
|
894
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
895
|
-
// Leaderboard Command
|
|
896
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
897
|
-
|
|
898
|
-
function LeaderboardCommand({ datasetId, limit }: { datasetId: string; limit?: number }) {
|
|
899
|
-
const { exit } = useApp();
|
|
900
|
-
const [state, setState] = useState<"loading" | "done" | "error">("loading");
|
|
901
|
-
const [data, setData] = useState<api.LeaderboardEntriesResponse | null>(null);
|
|
902
|
-
const [error, setError] = useState("");
|
|
903
|
-
|
|
904
|
-
useEffect(() => {
|
|
905
|
-
(async () => {
|
|
906
|
-
const result = await api.getLeaderboardEntries(datasetId, limit);
|
|
907
|
-
if (result.ok && result.data) {
|
|
908
|
-
setData(result.data);
|
|
909
|
-
setState("done");
|
|
910
|
-
} else {
|
|
911
|
-
setError(result.error ?? "Unknown error");
|
|
912
|
-
setState("error");
|
|
913
|
-
}
|
|
914
|
-
setTimeout(() => exit(), 500);
|
|
915
|
-
})();
|
|
916
|
-
}, [datasetId, limit, exit]);
|
|
917
|
-
|
|
918
|
-
if (state === "loading") {
|
|
919
|
-
return <Loading message="Loading leaderboard..." />;
|
|
920
|
-
}
|
|
921
|
-
|
|
922
|
-
if (state === "error") {
|
|
923
|
-
return <ErrorMessage error={error} />;
|
|
924
|
-
}
|
|
925
|
-
|
|
926
|
-
if (!data || data.entries.length === 0) {
|
|
927
|
-
return (
|
|
928
|
-
<Box flexDirection="column">
|
|
929
|
-
<Text bold color="cyan">Leaderboard: {data?.dataset_name ?? datasetId}</Text>
|
|
930
|
-
<Text dimColor> No entries yet. Be the first to submit!</Text>
|
|
931
|
-
</Box>
|
|
932
|
-
);
|
|
933
|
-
}
|
|
934
|
-
|
|
935
|
-
return (
|
|
936
|
-
<Box flexDirection="column">
|
|
937
|
-
<Text bold color="cyan">Leaderboard: {data.dataset_name} ({data.total_entries} entries)</Text>
|
|
938
|
-
<Text> </Text>
|
|
939
|
-
{/* Header */}
|
|
940
|
-
<Box>
|
|
941
|
-
<Box width={6}><Text bold dimColor>Rank</Text></Box>
|
|
942
|
-
<Box width={22}><Text bold dimColor>Name</Text></Box>
|
|
943
|
-
<Box width={22}><Text bold dimColor>Model</Text></Box>
|
|
944
|
-
<Box width={10}><Text bold dimColor>F1</Text></Box>
|
|
945
|
-
<Box width={10}><Text bold dimColor>Precision</Text></Box>
|
|
946
|
-
<Box width={10}><Text bold dimColor>Recall</Text></Box>
|
|
947
|
-
</Box>
|
|
948
|
-
{/* Entries */}
|
|
949
|
-
{data.entries.map((entry, idx) => {
|
|
950
|
-
const rank = entry.rank ?? idx + 1;
|
|
951
|
-
const isFirst = rank === 1;
|
|
952
|
-
return (
|
|
953
|
-
<Box key={entry.id}>
|
|
954
|
-
<Box width={6}>
|
|
955
|
-
<Text color={isFirst ? "yellow" : undefined} bold={isFirst}>
|
|
956
|
-
{isFirst ? `#${rank}` : `#${rank}`}
|
|
957
|
-
</Text>
|
|
958
|
-
</Box>
|
|
959
|
-
<Box width={22}>
|
|
960
|
-
<Text color={isFirst ? "yellow" : undefined} bold={isFirst}>
|
|
961
|
-
{entry.display_name.substring(0, 20)}
|
|
962
|
-
</Text>
|
|
963
|
-
</Box>
|
|
964
|
-
<Box width={22}>
|
|
965
|
-
<Text color="cyan">{entry.model_name.substring(0, 20)}</Text>
|
|
966
|
-
</Box>
|
|
967
|
-
<Box width={10}>
|
|
968
|
-
<Text color="green" bold>{entry.f1_score.toFixed(4)}</Text>
|
|
969
|
-
</Box>
|
|
970
|
-
<Box width={10}>
|
|
971
|
-
<Text>{entry.precision_score?.toFixed(4) ?? "N/A"}</Text>
|
|
972
|
-
</Box>
|
|
973
|
-
<Box width={10}>
|
|
974
|
-
<Text>{entry.recall_score?.toFixed(4) ?? "N/A"}</Text>
|
|
975
|
-
</Box>
|
|
976
|
-
</Box>
|
|
977
|
-
);
|
|
978
|
-
})}
|
|
979
|
-
</Box>
|
|
980
|
-
);
|
|
981
|
-
}
|
|
982
|
-
|
|
983
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
984
|
-
// Job Create Command (with auto-upload for local datasets)
|
|
985
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
986
|
-
|
|
987
|
-
interface ParsedDataset {
|
|
988
|
-
type: "local" | "remote";
|
|
989
|
-
name?: string; // for remote name:version format
|
|
990
|
-
version?: string; // for remote name:version format
|
|
991
|
-
id?: string; // for remote UUID format
|
|
992
|
-
}
|
|
1748
|
+
interface ParsedDataset {
|
|
1749
|
+
type: "local" | "remote";
|
|
1750
|
+
name?: string; // for remote name:version format
|
|
1751
|
+
version?: string; // for remote name:version format
|
|
1752
|
+
id?: string; // for remote UUID format
|
|
1753
|
+
}
|
|
993
1754
|
|
|
994
1755
|
interface JobCreateCommandProps {
|
|
995
1756
|
modelName: string;
|
|
@@ -1607,11 +2368,54 @@ function DeployedModelCard({ model, index }: DeployedModelCardProps) {
|
|
|
1607
2368
|
);
|
|
1608
2369
|
}
|
|
1609
2370
|
|
|
2371
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
2372
|
+
// Registered Model (Project) Visualization Component
|
|
2373
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
2374
|
+
|
|
2375
|
+
interface ProjectModelCardProps {
|
|
2376
|
+
model: api.ProjectResponse;
|
|
2377
|
+
index: number;
|
|
2378
|
+
}
|
|
2379
|
+
|
|
2380
|
+
function ProjectModelCard({ model, index }: ProjectModelCardProps) {
|
|
2381
|
+
const formatDateShort = (dateStr: string | null | undefined) => {
|
|
2382
|
+
if (!dateStr) return "N/A";
|
|
2383
|
+
const date = new Date(dateStr);
|
|
2384
|
+
return date.toLocaleDateString() + " " + date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
2385
|
+
};
|
|
2386
|
+
|
|
2387
|
+
return (
|
|
2388
|
+
<Box flexDirection="column" marginTop={index > 0 ? 0 : 0}>
|
|
2389
|
+
<Box>
|
|
2390
|
+
<Text bold color="green">●</Text>
|
|
2391
|
+
<Text> </Text>
|
|
2392
|
+
<Box width={28}>
|
|
2393
|
+
<Text bold color="cyan">{model.name?.substring(0, 26) || "Unnamed"}</Text>
|
|
2394
|
+
</Box>
|
|
2395
|
+
<Box width={38}>
|
|
2396
|
+
<Text dimColor>{model.id}</Text>
|
|
2397
|
+
</Box>
|
|
2398
|
+
<Box width={24}>
|
|
2399
|
+
<Text color="magenta">{model.selected_model_id || "N/A"}</Text>
|
|
2400
|
+
</Box>
|
|
2401
|
+
<Box width={18}>
|
|
2402
|
+
<Text dimColor>{formatDateShort(model.created_at)}</Text>
|
|
2403
|
+
</Box>
|
|
2404
|
+
</Box>
|
|
2405
|
+
{model.description && (
|
|
2406
|
+
<Box marginLeft={2}>
|
|
2407
|
+
<Text dimColor>{model.description}</Text>
|
|
2408
|
+
</Box>
|
|
2409
|
+
)}
|
|
2410
|
+
</Box>
|
|
2411
|
+
);
|
|
2412
|
+
}
|
|
2413
|
+
|
|
1610
2414
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
1611
2415
|
// Model List Command
|
|
1612
2416
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
1613
2417
|
|
|
1614
|
-
type ModelListFilter = "
|
|
2418
|
+
type ModelListFilter = "registered" | "trained" | "deployed" | "artifacts";
|
|
1615
2419
|
|
|
1616
2420
|
interface ModelListCommandProps {
|
|
1617
2421
|
filter: ModelListFilter;
|
|
@@ -1645,11 +2449,42 @@ function ModelListCommand({ filter }: ModelListCommandProps) {
|
|
|
1645
2449
|
return <ErrorMessage error={error} />;
|
|
1646
2450
|
}
|
|
1647
2451
|
|
|
1648
|
-
const
|
|
1649
|
-
const
|
|
2452
|
+
const showProjects = filter === "registered";
|
|
2453
|
+
const showDeployed = filter === "deployed" || filter === "artifacts";
|
|
2454
|
+
const showTrained = filter === "trained" || filter === "artifacts";
|
|
1650
2455
|
|
|
1651
2456
|
return (
|
|
1652
2457
|
<Box flexDirection="column">
|
|
2458
|
+
{showProjects && (
|
|
2459
|
+
<>
|
|
2460
|
+
<Text bold color="cyan">Model Entries ({data?.projects.length ?? 0})</Text>
|
|
2461
|
+
{data?.projects.length === 0 ? (
|
|
2462
|
+
<Text dimColor> No model entries</Text>
|
|
2463
|
+
) : (
|
|
2464
|
+
<Box flexDirection="column" marginTop={1}>
|
|
2465
|
+
<Box marginBottom={0}>
|
|
2466
|
+
<Text bold dimColor> </Text>
|
|
2467
|
+
<Box width={28}>
|
|
2468
|
+
<Text bold dimColor>Name</Text>
|
|
2469
|
+
</Box>
|
|
2470
|
+
<Box width={38}>
|
|
2471
|
+
<Text bold dimColor>Model ID</Text>
|
|
2472
|
+
</Box>
|
|
2473
|
+
<Box width={24}>
|
|
2474
|
+
<Text bold dimColor>Base Model</Text>
|
|
2475
|
+
</Box>
|
|
2476
|
+
<Box width={18}>
|
|
2477
|
+
<Text bold dimColor>Created</Text>
|
|
2478
|
+
</Box>
|
|
2479
|
+
</Box>
|
|
2480
|
+
{data?.projects.map((model, index) => (
|
|
2481
|
+
<ProjectModelCard key={model.id || index} model={model} index={index} />
|
|
2482
|
+
))}
|
|
2483
|
+
</Box>
|
|
2484
|
+
)}
|
|
2485
|
+
</>
|
|
2486
|
+
)}
|
|
2487
|
+
{showProjects && (showDeployed || showTrained) && <Text> </Text>}
|
|
1653
2488
|
{showDeployed && (
|
|
1654
2489
|
<>
|
|
1655
2490
|
<Text bold color="cyan">Deployed Models ({data?.deployed.length ?? 0})</Text>
|
|
@@ -1728,11 +2563,281 @@ function ModelListCommand({ filter }: ModelListCommandProps) {
|
|
|
1728
2563
|
);
|
|
1729
2564
|
}
|
|
1730
2565
|
|
|
2566
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
2567
|
+
// Model Generate Command (decoder pre-check + better errors)
|
|
2568
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
2569
|
+
|
|
2570
|
+
interface ModelGenerateCommandProps {
|
|
2571
|
+
modelId: string;
|
|
2572
|
+
prompt: string;
|
|
2573
|
+
systemMsg?: string;
|
|
2574
|
+
maxTokens: number;
|
|
2575
|
+
temperature: number;
|
|
2576
|
+
topP?: number;
|
|
2577
|
+
includeReasoningTrace?: boolean;
|
|
2578
|
+
projectId?: string;
|
|
2579
|
+
}
|
|
2580
|
+
|
|
2581
|
+
function normalizeBaseModels(
|
|
2582
|
+
data: api.BaseModelsResponse | api.BaseModelInfo[] | null | undefined
|
|
2583
|
+
): api.BaseModelInfo[] {
|
|
2584
|
+
if (!data) return [];
|
|
2585
|
+
if (Array.isArray(data)) return data;
|
|
2586
|
+
if (Array.isArray(data.models)) return data.models;
|
|
2587
|
+
return [];
|
|
2588
|
+
}
|
|
2589
|
+
|
|
2590
|
+
function isUuid(value: string): boolean {
|
|
2591
|
+
return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(
|
|
2592
|
+
value
|
|
2593
|
+
);
|
|
2594
|
+
}
|
|
2595
|
+
|
|
2596
|
+
function formatDecoderSuggestions(decoderIds: string[]): string {
|
|
2597
|
+
if (decoderIds.length === 0) return "";
|
|
2598
|
+
return `\nTry one of these decoder models: ${decoderIds.slice(0, 4).join(", ")}`;
|
|
2599
|
+
}
|
|
2600
|
+
|
|
2601
|
+
function normalizeModelId(modelId: string): string {
|
|
2602
|
+
return modelId.trim();
|
|
2603
|
+
}
|
|
2604
|
+
|
|
2605
|
+
function getDecoderTaskType(model: api.BaseModelInfo | null | undefined): string {
|
|
2606
|
+
if (!model) return "";
|
|
2607
|
+
return `${model.task_type ?? model.type ?? ""}`.trim().toLowerCase();
|
|
2608
|
+
}
|
|
2609
|
+
|
|
2610
|
+
function modelSupportsDecoderInference(model: api.BaseModelInfo | null | undefined): boolean {
|
|
2611
|
+
if (!model) return false;
|
|
2612
|
+
if (model.supports_inference !== undefined) {
|
|
2613
|
+
return model.supports_inference;
|
|
2614
|
+
}
|
|
2615
|
+
if (model.supports_on_demand_inference !== undefined) {
|
|
2616
|
+
return model.supports_on_demand_inference;
|
|
2617
|
+
}
|
|
2618
|
+
return true;
|
|
2619
|
+
}
|
|
2620
|
+
|
|
2621
|
+
function isDecoderModel(model: api.BaseModelInfo | null | undefined): boolean {
|
|
2622
|
+
const taskType = getDecoderTaskType(model);
|
|
2623
|
+
return (
|
|
2624
|
+
taskType === "decoder" ||
|
|
2625
|
+
taskType === "llm" ||
|
|
2626
|
+
taskType === "generative"
|
|
2627
|
+
);
|
|
2628
|
+
}
|
|
2629
|
+
|
|
2630
|
+
function shouldFallbackToTextCompletions(errorMessage: string): boolean {
|
|
2631
|
+
const normalized = errorMessage.toLowerCase();
|
|
2632
|
+
return (
|
|
2633
|
+
normalized.includes("/v1/completions") ||
|
|
2634
|
+
normalized.includes("without a chat template") ||
|
|
2635
|
+
normalized.includes("text completion")
|
|
2636
|
+
);
|
|
2637
|
+
}
|
|
2638
|
+
|
|
2639
|
+
function buildTextCompletionPrompt(prompt: string, systemMsg?: string): string {
|
|
2640
|
+
if (!systemMsg) return prompt;
|
|
2641
|
+
return `System instruction:\n${systemMsg}\n\nUser prompt:\n${prompt}\n\nAssistant response:`;
|
|
2642
|
+
}
|
|
2643
|
+
|
|
2644
|
+
function parseCommaSeparated(value?: string): string[] {
|
|
2645
|
+
if (!value) return [];
|
|
2646
|
+
return value
|
|
2647
|
+
.split(",")
|
|
2648
|
+
.map((item) => item.trim())
|
|
2649
|
+
.filter(Boolean);
|
|
2650
|
+
}
|
|
2651
|
+
|
|
2652
|
+
function ModelGenerateCommand({
|
|
2653
|
+
modelId,
|
|
2654
|
+
prompt,
|
|
2655
|
+
systemMsg,
|
|
2656
|
+
maxTokens,
|
|
2657
|
+
temperature,
|
|
2658
|
+
topP,
|
|
2659
|
+
includeReasoningTrace,
|
|
2660
|
+
projectId,
|
|
2661
|
+
}: ModelGenerateCommandProps) {
|
|
2662
|
+
const { exit } = useApp();
|
|
2663
|
+
const [state, setState] = useState<"checking" | "running" | "done" | "error">(
|
|
2664
|
+
"checking"
|
|
2665
|
+
);
|
|
2666
|
+
const [data, setData] = useState<api.InferenceResponse | api.TextCompletionResponse | null>(
|
|
2667
|
+
null
|
|
2668
|
+
);
|
|
2669
|
+
const [error, setError] = useState("");
|
|
2670
|
+
|
|
2671
|
+
useEffect(() => {
|
|
2672
|
+
let active = true;
|
|
2673
|
+
|
|
2674
|
+
(async () => {
|
|
2675
|
+
const baseModelsResult = await api.listBaseModels();
|
|
2676
|
+
const baseModels =
|
|
2677
|
+
baseModelsResult.ok && baseModelsResult.data
|
|
2678
|
+
? normalizeBaseModels(baseModelsResult.data)
|
|
2679
|
+
: [];
|
|
2680
|
+
const decoderModelIds = baseModels
|
|
2681
|
+
.filter((model) => isDecoderModel(model) && modelSupportsDecoderInference(model))
|
|
2682
|
+
.map((model) => model.id);
|
|
2683
|
+
const normalizedModelId = normalizeModelId(modelId);
|
|
2684
|
+
|
|
2685
|
+
const fail = (message: string) => {
|
|
2686
|
+
if (!active) return;
|
|
2687
|
+
setError(message);
|
|
2688
|
+
setState("error");
|
|
2689
|
+
setTimeout(() => exit(), 500);
|
|
2690
|
+
};
|
|
2691
|
+
|
|
2692
|
+
const matchedBaseModel = baseModels.find((model) => model.id === normalizedModelId);
|
|
2693
|
+
if (matchedBaseModel && (!isDecoderModel(matchedBaseModel) || !modelSupportsDecoderInference(matchedBaseModel))) {
|
|
2694
|
+
const modelName = matchedBaseModel.label || matchedBaseModel.name || matchedBaseModel.id;
|
|
2695
|
+
const taskType = getDecoderTaskType(matchedBaseModel) || "unknown";
|
|
2696
|
+
const supportsInference = modelSupportsDecoderInference(matchedBaseModel);
|
|
2697
|
+
fail(
|
|
2698
|
+
`Model '${modelName}' is type '${taskType}' and is not decoder-compatible for inference` +
|
|
2699
|
+
`${supportsInference ? "" : " (supports_inference = false)"} ` +
|
|
2700
|
+
`(supports_inference: ${String(matchedBaseModel.supports_inference ?? "unknown")}, task_type: ${taskType}).` +
|
|
2701
|
+
formatDecoderSuggestions(decoderModelIds)
|
|
2702
|
+
);
|
|
2703
|
+
return;
|
|
2704
|
+
}
|
|
2705
|
+
|
|
2706
|
+
if (baseModels.length > 0 && !isUuid(normalizedModelId) && !matchedBaseModel) {
|
|
2707
|
+
fail(
|
|
2708
|
+
`Model '${modelId}' is not a recognized decoder base model and is not a valid job UUID.` +
|
|
2709
|
+
` Use 'model list' to copy a full training job UUID or provide a known decoder catalog ID.`
|
|
2710
|
+
);
|
|
2711
|
+
return;
|
|
2712
|
+
}
|
|
2713
|
+
|
|
2714
|
+
if (isUuid(normalizedModelId)) {
|
|
2715
|
+
const jobResult = await api.getJob(normalizedModelId);
|
|
2716
|
+
if (jobResult.ok && jobResult.data) {
|
|
2717
|
+
const taskType = jobResult.data.task_type?.toLowerCase();
|
|
2718
|
+
if (taskType && !isDecoderModel({ task_type: taskType } as api.BaseModelInfo)) {
|
|
2719
|
+
fail(
|
|
2720
|
+
`Training job '${normalizedModelId}' has task_type '${taskType}', so it is not decoder-compatible.` +
|
|
2721
|
+
formatDecoderSuggestions(decoderModelIds)
|
|
2722
|
+
);
|
|
2723
|
+
return;
|
|
2724
|
+
}
|
|
2725
|
+
}
|
|
2726
|
+
}
|
|
2727
|
+
|
|
2728
|
+
if (!active) return;
|
|
2729
|
+
setState("running");
|
|
2730
|
+
|
|
2731
|
+
const messages: api.InferenceMessage[] = [];
|
|
2732
|
+
if (systemMsg) {
|
|
2733
|
+
messages.push({ role: "system", content: systemMsg });
|
|
2734
|
+
}
|
|
2735
|
+
messages.push({ role: "user", content: prompt });
|
|
2736
|
+
|
|
2737
|
+
const result = await api.runInference({
|
|
2738
|
+
model_id: normalizedModelId,
|
|
2739
|
+
task: "generate",
|
|
2740
|
+
messages,
|
|
2741
|
+
max_tokens: maxTokens,
|
|
2742
|
+
temperature,
|
|
2743
|
+
...(topP !== undefined ? { top_p: topP } : {}),
|
|
2744
|
+
...(includeReasoningTrace ? { include_reasoning_trace: true } : {}),
|
|
2745
|
+
...(projectId ? { project_id: projectId } : {}),
|
|
2746
|
+
});
|
|
2747
|
+
|
|
2748
|
+
if (!active) return;
|
|
2749
|
+
|
|
2750
|
+
if (result.ok && result.data) {
|
|
2751
|
+
setData(result.data);
|
|
2752
|
+
setState("done");
|
|
2753
|
+
} else {
|
|
2754
|
+
const primaryError = result.error ?? "Unknown error";
|
|
2755
|
+
const normalizedError = formatApiError(primaryError);
|
|
2756
|
+
let message = normalizedError;
|
|
2757
|
+
|
|
2758
|
+
if (shouldFallbackToTextCompletions(normalizedError)) {
|
|
2759
|
+
const completionResult = await api.runTextCompletion({
|
|
2760
|
+
model: normalizedModelId,
|
|
2761
|
+
prompt: buildTextCompletionPrompt(prompt, systemMsg),
|
|
2762
|
+
max_tokens: maxTokens,
|
|
2763
|
+
temperature,
|
|
2764
|
+
...(topP !== undefined ? { extra_body: { top_p: topP } } : {}),
|
|
2765
|
+
});
|
|
2766
|
+
|
|
2767
|
+
if (!active) return;
|
|
2768
|
+
|
|
2769
|
+
if (completionResult.ok && completionResult.data) {
|
|
2770
|
+
setData(completionResult.data);
|
|
2771
|
+
setState("done");
|
|
2772
|
+
setTimeout(() => exit(), 500);
|
|
2773
|
+
return;
|
|
2774
|
+
}
|
|
2775
|
+
|
|
2776
|
+
message =
|
|
2777
|
+
"Decoder chat inference failed, and raw text fallback via /v1/completions also failed.\n" +
|
|
2778
|
+
formatApiError(completionResult.error ?? "Unknown error");
|
|
2779
|
+
} else if (normalizedError.toLowerCase().includes("inference failed")) {
|
|
2780
|
+
message =
|
|
2781
|
+
`${normalizedError}\nDecoder inference request reached the backend but failed to execute.` +
|
|
2782
|
+
formatDecoderSuggestions(decoderModelIds);
|
|
2783
|
+
}
|
|
2784
|
+
setError(message);
|
|
2785
|
+
setState("error");
|
|
2786
|
+
}
|
|
2787
|
+
|
|
2788
|
+
setTimeout(() => exit(), 500);
|
|
2789
|
+
})();
|
|
2790
|
+
|
|
2791
|
+
return () => {
|
|
2792
|
+
active = false;
|
|
2793
|
+
};
|
|
2794
|
+
}, [
|
|
2795
|
+
modelId,
|
|
2796
|
+
prompt,
|
|
2797
|
+
systemMsg,
|
|
2798
|
+
maxTokens,
|
|
2799
|
+
temperature,
|
|
2800
|
+
topP,
|
|
2801
|
+
includeReasoningTrace,
|
|
2802
|
+
projectId,
|
|
2803
|
+
exit,
|
|
2804
|
+
]);
|
|
2805
|
+
|
|
2806
|
+
if (state === "checking") {
|
|
2807
|
+
return <Loading message="Checking decoder model compatibility..." />;
|
|
2808
|
+
}
|
|
2809
|
+
|
|
2810
|
+
if (state === "running") {
|
|
2811
|
+
return <Loading message="Running decoder inference..." />;
|
|
2812
|
+
}
|
|
2813
|
+
|
|
2814
|
+
if (state === "error") {
|
|
2815
|
+
return <ErrorMessage error={error} />;
|
|
2816
|
+
}
|
|
2817
|
+
|
|
2818
|
+
return (
|
|
2819
|
+
<Box flexDirection="column">
|
|
2820
|
+
{data && <JsonOutput data={data} />}
|
|
2821
|
+
</Box>
|
|
2822
|
+
);
|
|
2823
|
+
}
|
|
2824
|
+
|
|
1731
2825
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
1732
2826
|
// Help Components
|
|
1733
2827
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
1734
2828
|
|
|
1735
|
-
type HelpContext =
|
|
2829
|
+
type HelpContext =
|
|
2830
|
+
| "root"
|
|
2831
|
+
| "auth"
|
|
2832
|
+
| "dataset"
|
|
2833
|
+
| "dataset-analyze"
|
|
2834
|
+
| "dataset-edit"
|
|
2835
|
+
| "job"
|
|
2836
|
+
| "model"
|
|
2837
|
+
| "eval"
|
|
2838
|
+
| "benchmark"
|
|
2839
|
+
| "inference"
|
|
2840
|
+
| "agent";
|
|
1736
2841
|
|
|
1737
2842
|
interface HelpProps {
|
|
1738
2843
|
context?: HelpContext;
|
|
@@ -1778,6 +2883,7 @@ const Help: React.FC<HelpProps> = ({ context = "root" }) => {
|
|
|
1778
2883
|
<Text> dataset get {"<name[:version]>"} Get dataset details</Text>
|
|
1779
2884
|
<Text> dataset delete {"<name[:version]>"} Delete a dataset</Text>
|
|
1780
2885
|
<Text> dataset analyze {"<name[:version]>"} Analyze a dataset</Text>
|
|
2886
|
+
<Text> dataset analyze-llm {"<name[:version]>"} LLM-only dataset analysis</Text>
|
|
1781
2887
|
<Text> </Text>
|
|
1782
2888
|
<Text bold> Generate:</Text>
|
|
1783
2889
|
<Text> dataset generate ner</Text>
|
|
@@ -1802,11 +2908,59 @@ const Help: React.FC<HelpProps> = ({ context = "root" }) => {
|
|
|
1802
2908
|
<Text> --save true Save to database</Text>
|
|
1803
2909
|
<Text> --name {"<name>"} Dataset name (required if --save)</Text>
|
|
1804
2910
|
<Text> </Text>
|
|
2911
|
+
<Text> dataset generate decoder</Text>
|
|
2912
|
+
<Text> --domain {"<desc>"} Domain/task description (required)</Text>
|
|
2913
|
+
<Text> --instruction {"<text>"} System instruction (optional, auto-inferred)</Text>
|
|
2914
|
+
<Text> --num {"<n>"} Number of examples (default: 10)</Text>
|
|
2915
|
+
<Text> --save true Save to database</Text>
|
|
2916
|
+
<Text> --name {"<name>"} Dataset name (required if --save)</Text>
|
|
2917
|
+
<Text> Advanced generation flags:</Text>
|
|
2918
|
+
<Text> --quality {"<light|medium|heavy>"} Generation quality profile</Text>
|
|
2919
|
+
<Text> --generation-profile {"<auto|fast|balanced|quality>"} Runtime profile</Text>
|
|
2920
|
+
<Text> --reasoning-trace {"true|false"} Include reasoning traces (decoder only)</Text>
|
|
2921
|
+
<Text> --reasoning-effort {"<low|medium|high>"} Reasoning effort</Text>
|
|
2922
|
+
<Text> --multiplicator {"<json>"} Multiplicator settings</Text>
|
|
2923
|
+
<Text> --use-meta-felix {"true|false"} Use MetaFelix metadata</Text>
|
|
2924
|
+
<Text> --min-criteria {"<n>"} Minimum diversity criteria</Text>
|
|
2925
|
+
<Text> --target-choices {"<n>"} Diversity target choices</Text>
|
|
2926
|
+
<Text> --project-id {"<id>"} Project ID</Text>
|
|
2927
|
+
<Text> --type {"training|evaluation|split"} Dataset type</Text>
|
|
2928
|
+
<Text> --visibility {"private|public"} Dataset visibility</Text>
|
|
2929
|
+
<Text> --split-ratio {"<train:eval>|{json>}"} Split dataset ratio</Text>
|
|
2930
|
+
<Text> --negative-ratio {"<n>"} Percent negative samples</Text>
|
|
2931
|
+
<Text> --classified-examples {"<json>"} Classified examples with feedback</Text>
|
|
2932
|
+
<Text> </Text>
|
|
1805
2933
|
<Text bold> Infer Labels:</Text>
|
|
1806
2934
|
<Text> dataset infer ner Infer NER labels from description</Text>
|
|
1807
2935
|
<Text> dataset infer classification Infer classification labels</Text>
|
|
1808
2936
|
<Text> dataset infer fields Infer input/output fields</Text>
|
|
1809
2937
|
<Text> --domain {"<desc>"} Domain description (required)</Text>
|
|
2938
|
+
<Text> dataset infer infer-advanced Infer constraints and multiplicator from a prompt</Text>
|
|
2939
|
+
<Text> --prompt {"<prompt>"} Prompt for inference</Text>
|
|
2940
|
+
<Text> --labels {"<l1,l2,...>"} Optional labels to guide suggestions</Text>
|
|
2941
|
+
<Text> --data-type {"<type>"} entity_extraction|classification|json_extraction</Text>
|
|
2942
|
+
<Text> dataset infer improve-prompt Improve a generation prompt</Text>
|
|
2943
|
+
<Text> --prompt {"<prompt>"} Prompt to improve</Text>
|
|
2944
|
+
<Text> --data-type {"<type>"} Optional prompt domain hint</Text>
|
|
2945
|
+
<Text> dataset label-existing ner Label existing NER texts</Text>
|
|
2946
|
+
<Text> --labels {"<l1,l2,...>"} Labels for entities</Text>
|
|
2947
|
+
<Text> --inputs {"[{\"text\":\"...\"},...]"} Input texts JSON array (required)</Text>
|
|
2948
|
+
<Text> --name {"<name>"} Output dataset name (optional if --save false)</Text>
|
|
2949
|
+
<Text> --project-id {"<project_id>"} Assign output dataset to project</Text>
|
|
2950
|
+
<Text> --save {"<true|false>"} Save dataset (default: false)</Text>
|
|
2951
|
+
<Text> dataset label-existing classification Label existing classification texts</Text>
|
|
2952
|
+
<Text> --labels {"<l1,l2,...>"} Labels for classes</Text>
|
|
2953
|
+
<Text> --inputs {"[{\"text\":\"...\"},...]"} Input texts JSON array (required)</Text>
|
|
2954
|
+
<Text> --name {"<name>"} Output dataset name (optional if --save false)</Text>
|
|
2955
|
+
<Text> --project-id {"<project_id>"} Assign output dataset to project</Text>
|
|
2956
|
+
<Text> --save {"<true|false>"} Save dataset (default: false)</Text>
|
|
2957
|
+
<Text> dataset label-existing fields Label existing structured records</Text>
|
|
2958
|
+
<Text> --input-fields {"[{\"name\":\"...\"},...]"} Input schema fields (required)</Text>
|
|
2959
|
+
<Text> --output-fields {"[{\"name\":\"...\"},...]"} Output schema fields (required)</Text>
|
|
2960
|
+
<Text> --inputs {"[{\"f1\":\"v\"},...]"} Input records JSON array (required)</Text>
|
|
2961
|
+
<Text> --name {"<name>"} Output dataset name (optional if --save false)</Text>
|
|
2962
|
+
<Text> --project-id {"<project_id>"} Assign output dataset to project</Text>
|
|
2963
|
+
<Text> --save {"<true|false>"} Save dataset (default: false)</Text>
|
|
1810
2964
|
<Text> </Text>
|
|
1811
2965
|
<Text bold> Upload/Download:</Text>
|
|
1812
2966
|
<Text> dataset upload {"<file>"} Upload local file to Pioneer</Text>
|
|
@@ -1828,6 +2982,8 @@ const Help: React.FC<HelpProps> = ({ context = "root" }) => {
|
|
|
1828
2982
|
<Text bold> Data Editing:</Text>
|
|
1829
2983
|
<Text> dataset edit --help Show data editing commands</Text>
|
|
1830
2984
|
<Text> dataset edit scan-pii {"<name[:version]>"} Scan for PII</Text>
|
|
2985
|
+
<Text> dataset edit dismiss-outlier {"<name[:version]>"} Dismiss an outlier fingerprint</Text>
|
|
2986
|
+
<Text> --fingerprint {"<hash>"} Outlier fingerprint from dataset analysis</Text>
|
|
1831
2987
|
<Text> dataset edit subsample {"<name[:version]>"} Create a subsample</Text>
|
|
1832
2988
|
</Box>
|
|
1833
2989
|
);
|
|
@@ -1846,6 +3002,8 @@ const Help: React.FC<HelpProps> = ({ context = "root" }) => {
|
|
|
1846
3002
|
<Text> dataset edit scan-phd {"<name[:version]>"} Scan for prompt injection</Text>
|
|
1847
3003
|
<Text> --columns {"<col1,col2>"} Columns to scan (optional, scans all if omitted)</Text>
|
|
1848
3004
|
<Text> --threshold {"<n>"} Detection threshold (default: 0.5)</Text>
|
|
3005
|
+
<Text> dataset edit dismiss-outlier {"<name[:version]>"} Dismiss an outlier fingerprint</Text>
|
|
3006
|
+
<Text> --fingerprint {"<hash>"} Outlier fingerprint from dataset analysis</Text>
|
|
1849
3007
|
<Text> dataset edit subsample {"<name[:version]>"} Create a subsample</Text>
|
|
1850
3008
|
<Text> --n {"<count>"} Target sample count (required)</Text>
|
|
1851
3009
|
<Text> --method {"<type>"} Method: random, balanced, stratified</Text>
|
|
@@ -1873,9 +3031,13 @@ const Help: React.FC<HelpProps> = ({ context = "root" }) => {
|
|
|
1873
3031
|
<Text> Options: ner, classification, generative</Text>
|
|
1874
3032
|
<Text> --analyses {"<a1,a2,...>"} Analyses to run (required, comma-separated)</Text>
|
|
1875
3033
|
<Text> Options: distribution, duplicates, outliers, splits, diversity</Text>
|
|
3034
|
+
<Text> </Text>
|
|
3035
|
+
<Text> LLM-only analysis:</Text>
|
|
3036
|
+
<Text> dataset analyze-llm {"<id>"} --task-type {"<type>"} --description {"<text>"} --labels {"<l1,l2>"} </Text>
|
|
1876
3037
|
<Text> </Text>
|
|
1877
3038
|
<Text bold> Example:</Text>
|
|
1878
3039
|
<Text> dataset analyze abc123 --task-type ner --analyses distribution,duplicates</Text>
|
|
3040
|
+
<Text> dataset analyze-llm abc123 --task-type ner --description "NER quality analysis"</Text>
|
|
1879
3041
|
</Box>
|
|
1880
3042
|
);
|
|
1881
3043
|
}
|
|
@@ -1901,89 +3063,139 @@ const Help: React.FC<HelpProps> = ({ context = "root" }) => {
|
|
|
1901
3063
|
);
|
|
1902
3064
|
}
|
|
1903
3065
|
|
|
1904
|
-
// Model help
|
|
1905
|
-
if (context === "model") {
|
|
3066
|
+
// Model endpoints help
|
|
3067
|
+
if (context === "model-endpoints") {
|
|
1906
3068
|
return (
|
|
1907
3069
|
<Box flexDirection="column">
|
|
1908
|
-
<Text bold>Model Commands:</Text>
|
|
1909
|
-
<Text>
|
|
1910
|
-
<Text> model list
|
|
1911
|
-
<Text> model
|
|
1912
|
-
<Text>
|
|
1913
|
-
<Text>
|
|
1914
|
-
<Text> </Text>
|
|
1915
|
-
<Text
|
|
1916
|
-
<Text>
|
|
1917
|
-
<Text> --
|
|
1918
|
-
<Text>
|
|
1919
|
-
<Text
|
|
1920
|
-
<Text
|
|
3070
|
+
<Text bold>Model Endpoint Commands:</Text>
|
|
3071
|
+
<Text> Aliases: model_endpoints ...</Text>
|
|
3072
|
+
<Text> model endpoints list</Text>
|
|
3073
|
+
<Text> model endpoints create</Text>
|
|
3074
|
+
<Text> --name {"<name>"} Optional (defaults to model id)</Text>
|
|
3075
|
+
<Text> --icon {"<icon>"} Optional</Text>
|
|
3076
|
+
<Text> --repo {"<repo-url>"} Optional</Text>
|
|
3077
|
+
<Text> --description {"<text>"} Optional</Text>
|
|
3078
|
+
<Text> --model {"<base-model-id>"} Optional (starts interactive picker when omitted)</Text>
|
|
3079
|
+
<Text> --example {"<json>"} Optional</Text>
|
|
3080
|
+
<Text> model endpoints get {"<model-id>"} Get endpoint/model entry details</Text>
|
|
3081
|
+
<Text> model endpoints update {"<model-id>"} Update endpoint metadata</Text>
|
|
3082
|
+
<Text> --name {"<name>"} --icon {"<icon>"} --repo {"<repo-url>"} --description {"<text>"} --model-id {"<id>"}</Text>
|
|
3083
|
+
<Text> model endpoints delete {"<model-id>"} Delete an endpoint/model entry</Text>
|
|
3084
|
+
<Text> model endpoints dataset-count {"<model-id>"} Get attached dataset count</Text>
|
|
3085
|
+
<Text> model endpoints quality-metrics {"<model-id>"} Show LLMAJ pass/fail metrics</Text>
|
|
3086
|
+
<Text> model endpoints deploy {"<model-id>"} --job {"<training-job-id>"} [--reason {"<text>"}] Deploy a trained job to the endpoint</Text>
|
|
3087
|
+
<Text> model endpoints rollback {"<model-id>"} {"<deployment-id>"} Rollback endpoint to previous deployment</Text>
|
|
1921
3088
|
</Box>
|
|
1922
3089
|
);
|
|
1923
3090
|
}
|
|
1924
3091
|
|
|
1925
|
-
//
|
|
1926
|
-
if (context === "
|
|
3092
|
+
// Model artifacts help
|
|
3093
|
+
if (context === "model-artifacts") {
|
|
1927
3094
|
return (
|
|
1928
3095
|
<Box flexDirection="column">
|
|
1929
|
-
<Text bold>
|
|
1930
|
-
<Text>
|
|
1931
|
-
<Text>
|
|
1932
|
-
<Text> </Text>
|
|
1933
|
-
<Text
|
|
3096
|
+
<Text bold>Model Artifact Commands:</Text>
|
|
3097
|
+
<Text> Aliases: model_artifacts ...</Text>
|
|
3098
|
+
<Text> model artifacts list Show both trained and deployed artifacts</Text>
|
|
3099
|
+
<Text> model artifacts trained List trained artifacts</Text>
|
|
3100
|
+
<Text> model artifacts deployed List deployed artifacts</Text>
|
|
3101
|
+
<Text> model artifacts download {"<job-id>"} Download model artifact</Text>
|
|
3102
|
+
<Text> model artifacts delete {"<job-id>"} Delete deployed artifact record</Text>
|
|
3103
|
+
<Text> model artifacts upload {"<job-id>"} --to hf Upload trained model artifact to Hugging Face</Text>
|
|
3104
|
+
<Text> --repo {"<repo>"} HF repo (required, e.g., username/model)</Text>
|
|
3105
|
+
<Text> --private Make repo private</Text>
|
|
3106
|
+
<Text dimColor> Note: Set HF token with 'pioneer auth hf' first</Text>
|
|
3107
|
+
<Text dimColor> Note: Use full job ID (not partial ID shown in list)</Text>
|
|
1934
3108
|
</Box>
|
|
1935
3109
|
);
|
|
1936
3110
|
}
|
|
1937
3111
|
|
|
1938
|
-
//
|
|
1939
|
-
if (context === "
|
|
3112
|
+
// Model help
|
|
3113
|
+
if (context === "model") {
|
|
1940
3114
|
return (
|
|
1941
3115
|
<Box flexDirection="column">
|
|
1942
|
-
<Text bold>
|
|
1943
|
-
<Text
|
|
3116
|
+
<Text bold>Model Commands:</Text>
|
|
3117
|
+
<Text> model endpoints ... (alias: model_endpoints) Manage model catalog entries (from /projects)</Text>
|
|
3118
|
+
<Text> model artifacts ... (alias: model_artifacts) Manage trained/deployed artifacts (from /felix)</Text>
|
|
3119
|
+
<Text> </Text>
|
|
3120
|
+
<Text> model endpoints list</Text>
|
|
3121
|
+
<Text> model endpoints create</Text>
|
|
3122
|
+
<Text> model endpoints get {"<model-id>"}</Text>
|
|
3123
|
+
<Text> model endpoints deploy {"<model-id>"} --job {"<training-job-id>"} [--reason {"<text>"}]</Text>
|
|
3124
|
+
<Text> model endpoints rollback {"<model-id>"} {"<deployment-id>"}</Text>
|
|
3125
|
+
<Text> model artifacts list</Text>
|
|
3126
|
+
<Text> model artifacts trained</Text>
|
|
3127
|
+
<Text> model artifacts deployed</Text>
|
|
3128
|
+
<Text> model artifacts download {"<job-id>"}</Text>
|
|
1944
3129
|
<Text> </Text>
|
|
1945
|
-
<Text> eval list {"<name[:version]>"} List evaluations for a dataset</Text>
|
|
1946
|
-
<Text> eval get {"<id>"} Get evaluation details</Text>
|
|
1947
|
-
<Text> eval create Create a new evaluation</Text>
|
|
1948
|
-
<Text> --model-id {"<id>"} Model to evaluate (required)</Text>
|
|
1949
|
-
<Text> --dataset {"<name[:version]>"} Dataset to evaluate on (required)</Text>
|
|
1950
|
-
<Text> --task-type {"<type>"} Task type: ner, classification</Text>
|
|
1951
|
-
<Text> --text-column {"<col>"} Text column name</Text>
|
|
1952
|
-
<Text> --label-column {"<col>"} Label column name</Text>
|
|
1953
3130
|
</Box>
|
|
1954
3131
|
);
|
|
1955
3132
|
}
|
|
1956
3133
|
|
|
1957
|
-
//
|
|
1958
|
-
if (context === "
|
|
3134
|
+
// Inference help
|
|
3135
|
+
if (context === "inference") {
|
|
1959
3136
|
return (
|
|
1960
3137
|
<Box flexDirection="column">
|
|
1961
|
-
<Text bold>
|
|
1962
|
-
<Text>
|
|
1963
|
-
<Text>
|
|
1964
|
-
<Text>
|
|
1965
|
-
<Text>
|
|
1966
|
-
<Text>
|
|
1967
|
-
<Text> --
|
|
1968
|
-
<Text> --
|
|
1969
|
-
<Text>
|
|
1970
|
-
<Text>
|
|
3138
|
+
<Text bold>Inference Commands:</Text>
|
|
3139
|
+
<Text> inference base-models</Text>
|
|
3140
|
+
<Text> List base models from /base-models</Text>
|
|
3141
|
+
<Text> </Text>
|
|
3142
|
+
<Text> inference encoder {"<model-id>"} --text {"<text>"} --labels {"<labels>"}</Text>
|
|
3143
|
+
<Text> Run encoder inference via /inference</Text>
|
|
3144
|
+
<Text> --task {"<task>"} extract_entities | classify_text | extract_json | schema</Text>
|
|
3145
|
+
<Text> --labels {"<labels>"} Comma-separated labels (or use --schema JSON)</Text>
|
|
3146
|
+
<Text> --schema {"<json>"} JSON schema object for advanced tasks</Text>
|
|
3147
|
+
<Text> --threshold {"<n>"} Confidence threshold (0-1, default: 0.5)</Text>
|
|
3148
|
+
<Text> --project-id {"<id>"} Associate inference with a project</Text>
|
|
3149
|
+
<Text> </Text>
|
|
3150
|
+
<Text> inference decoder {"<model-id>"} --prompt {"<text>"}</Text>
|
|
3151
|
+
<Text> Run decoder generation via /inference</Text>
|
|
3152
|
+
<Text> --system {"<text>"} System message (optional)</Text>
|
|
3153
|
+
<Text> --max-tokens {"<n>"} Max tokens (default: 256)</Text>
|
|
3154
|
+
<Text> --temperature {"<n>"} Sampling temperature (default: 0.7)</Text>
|
|
3155
|
+
<Text> --top-p {"<n>"} Top-p sampling (0-1)</Text>
|
|
3156
|
+
<Text> --reasoning-trace Include reasoning trace when supported</Text>
|
|
3157
|
+
<Text> --project-id {"<id>"} Associate inference with a project</Text>
|
|
3158
|
+
<Text> Example model IDs: Qwen/Qwen3-8B, meta-llama/Llama-3.1-8B-Instruct</Text>
|
|
3159
|
+
<Text> </Text>
|
|
3160
|
+
<Text> inference completions {"<model-id>"} --prompt {"<text>"}</Text>
|
|
3161
|
+
<Text> Run raw text completion via /v1/completions</Text>
|
|
3162
|
+
<Text> --max-tokens {"<n>"} Max tokens (default: 256)</Text>
|
|
3163
|
+
<Text> --temperature {"<n>"} Sampling temperature (default: 0.7)</Text>
|
|
3164
|
+
<Text> --top-p {"<n>"} Top-p (sent via extra_body)</Text>
|
|
3165
|
+
<Text> --stop {"<a,b,c>"} Stop sequences (comma-separated)</Text>
|
|
3166
|
+
<Text> --echo true Echo prompt in output</Text>
|
|
3167
|
+
<Text> --provider {"<name>"} Provider override (optional)</Text>
|
|
1971
3168
|
</Box>
|
|
1972
3169
|
);
|
|
1973
3170
|
}
|
|
1974
3171
|
|
|
1975
|
-
//
|
|
1976
|
-
if (context === "
|
|
3172
|
+
// Eval help
|
|
3173
|
+
if (context === "eval") {
|
|
3174
|
+
return <ErrorMessage error="The 'eval' command group is temporarily hidden for this version." />;
|
|
3175
|
+
}
|
|
3176
|
+
|
|
3177
|
+
// Benchmark help
|
|
3178
|
+
if (context === "benchmark") {
|
|
3179
|
+
return <ErrorMessage error="The 'benchmark' command group is temporarily hidden for this version." />;
|
|
3180
|
+
}
|
|
3181
|
+
|
|
3182
|
+
// Agent help
|
|
3183
|
+
if (context === "agent") {
|
|
1977
3184
|
return (
|
|
1978
3185
|
<Box flexDirection="column">
|
|
1979
|
-
<Text bold>
|
|
1980
|
-
<Text>
|
|
1981
|
-
<Text>
|
|
1982
|
-
<Text>
|
|
1983
|
-
<Text> --
|
|
1984
|
-
<Text>
|
|
1985
|
-
<Text> --
|
|
1986
|
-
<Text> --
|
|
3186
|
+
<Text bold>Agent Commands:</Text>
|
|
3187
|
+
<Text> agent Start interactive agent chat</Text>
|
|
3188
|
+
<Text> --mode {"<research>"} --mode research uses Pro workflow</Text>
|
|
3189
|
+
<Text> </Text>
|
|
3190
|
+
<Text> Omit --mode to use the default standard interactive mode.</Text>
|
|
3191
|
+
<Text> --conversation-id {"<id>"} Continue an existing conversation</Text>
|
|
3192
|
+
<Text> --filters {"<json>"} Reserved for future query filters</Text>
|
|
3193
|
+
<Text> --history {"<json>"} Optional message history JSON</Text>
|
|
3194
|
+
<Text> </Text>
|
|
3195
|
+
<Text dimColor>Example: pioneer agent</Text>
|
|
3196
|
+
<Text dimColor>Example: pioneer agent --mode research</Text>
|
|
3197
|
+
<Text dimColor>Then type: Analyze failures and propose retraining plan</Text>
|
|
3198
|
+
<Text dimColor>Then type: Draft a short status summary</Text>
|
|
1987
3199
|
</Box>
|
|
1988
3200
|
);
|
|
1989
3201
|
}
|
|
@@ -1997,14 +3209,10 @@ const Help: React.FC<HelpProps> = ({ context = "root" }) => {
|
|
|
1997
3209
|
<Text> pioneer {"<command>"} {"[options]"}</Text>
|
|
1998
3210
|
<Text> </Text>
|
|
1999
3211
|
<Text bold>Commands:</Text>
|
|
2000
|
-
<Text> chat Start interactive chat agent</Text>
|
|
2001
3212
|
<Text> auth Authentication (login, logout, status)</Text>
|
|
2002
|
-
<Text>
|
|
3213
|
+
<Text> model Manage model endpoints and artifacts</Text>
|
|
2003
3214
|
<Text> job Manage training jobs</Text>
|
|
2004
|
-
|
|
2005
|
-
<Text> eval Model evaluations on datasets</Text>
|
|
2006
|
-
<Text> benchmark Run benchmark evaluations</Text>
|
|
2007
|
-
<Text> competition Competitions and leaderboards</Text>
|
|
3215
|
+
<Text> agent Run agent chat (research is the only explicit alternate mode)</Text>
|
|
2008
3216
|
<Text> telemetry Manage anonymous usage analytics</Text>
|
|
2009
3217
|
<Text> </Text>
|
|
2010
3218
|
<Text dimColor>Run 'pioneer {"<command>"} --help' for details on a specific command.</Text>
|
|
@@ -2012,24 +3220,12 @@ const Help: React.FC<HelpProps> = ({ context = "root" }) => {
|
|
|
2012
3220
|
<Text dimColor>Get started:</Text>
|
|
2013
3221
|
<Text dimColor> 1. Sign up at https://app.pioneer.ai</Text>
|
|
2014
3222
|
<Text dimColor> 2. Run: pioneer auth login</Text>
|
|
2015
|
-
<Text dimColor> 3. Start building with: pioneer
|
|
3223
|
+
<Text dimColor> 3. Start building with: pioneer agent</Text>
|
|
2016
3224
|
</Box>
|
|
2017
3225
|
);
|
|
2018
3226
|
};
|
|
2019
3227
|
|
|
2020
3228
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
2021
|
-
// Chat Wrapper Component
|
|
2022
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
2023
|
-
|
|
2024
|
-
interface ChatWrapperProps {
|
|
2025
|
-
flags: Record<string, string>;
|
|
2026
|
-
}
|
|
2027
|
-
|
|
2028
|
-
const ChatWrapper: React.FC<ChatWrapperProps> = ({ flags }) => {
|
|
2029
|
-
const initialMessage = flags.message;
|
|
2030
|
-
return <ChatApp initialMessage={initialMessage} />;
|
|
2031
|
-
};
|
|
2032
|
-
|
|
2033
3229
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
2034
3230
|
// Main Router
|
|
2035
3231
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -2037,13 +3233,75 @@ const ChatWrapper: React.FC<ChatWrapperProps> = ({ flags }) => {
|
|
|
2037
3233
|
interface AppProps {
|
|
2038
3234
|
command: string[];
|
|
2039
3235
|
flags: Record<string, string>;
|
|
3236
|
+
parseErrors: string[];
|
|
2040
3237
|
}
|
|
2041
3238
|
|
|
2042
|
-
const App: React.FC<AppProps> = ({ command, flags }) => {
|
|
3239
|
+
const App: React.FC<AppProps> = ({ command, flags, parseErrors }) => {
|
|
2043
3240
|
// Check if raw mode is supported for interactive prompts
|
|
2044
3241
|
const { isRawModeSupported } = useStdin();
|
|
2045
3242
|
const [showTelemetryPrompt, setShowTelemetryPrompt] = useState(!hasChosenTelemetry());
|
|
2046
3243
|
const [group, action, ...rest] = command;
|
|
3244
|
+
const normalizedAction =
|
|
3245
|
+
action === "model_endpoints"
|
|
3246
|
+
? "endpoints"
|
|
3247
|
+
: action === "model_artifacts"
|
|
3248
|
+
? "artifacts"
|
|
3249
|
+
: action;
|
|
3250
|
+
const hasParseErrors = parseErrors.length > 0;
|
|
3251
|
+
const isModelCreateMissingModel =
|
|
3252
|
+
group === "model" &&
|
|
3253
|
+
normalizedAction === "endpoints" &&
|
|
3254
|
+
rest[0] === "create" &&
|
|
3255
|
+
parseErrors.length === 1 &&
|
|
3256
|
+
parseErrors[0] === "--model";
|
|
3257
|
+
const isModelEndpointsDeployMissingJob =
|
|
3258
|
+
group === "model" &&
|
|
3259
|
+
normalizedAction === "endpoints" &&
|
|
3260
|
+
rest[0] === "deploy" &&
|
|
3261
|
+
!flags["job"];
|
|
3262
|
+
|
|
3263
|
+
if (group === "dataset" || group === "inference" || group === "eval" || group === "benchmark") {
|
|
3264
|
+
return (
|
|
3265
|
+
<ErrorMessage
|
|
3266
|
+
error={`The '${group}' command group is temporarily hidden for this version. Use 'pioneer --help' to see available commands.`}
|
|
3267
|
+
/>
|
|
3268
|
+
);
|
|
3269
|
+
}
|
|
3270
|
+
|
|
3271
|
+
if (hasParseErrors && !isModelCreateMissingModel) {
|
|
3272
|
+
if (isModelEndpointsDeployMissingJob) {
|
|
3273
|
+
const errorMessage = rest[1]
|
|
3274
|
+
? `Training job ID required: model endpoints deploy ${rest[1]} --job <training-job-id>`
|
|
3275
|
+
: "Training job ID required: model endpoints deploy <model-id> --job <training-job-id>";
|
|
3276
|
+
|
|
3277
|
+
return (
|
|
3278
|
+
<ApiCommand
|
|
3279
|
+
action={() =>
|
|
3280
|
+
Promise.resolve<api.ApiResult<{ message: string }>>({
|
|
3281
|
+
ok: false,
|
|
3282
|
+
status: 400,
|
|
3283
|
+
error: errorMessage,
|
|
3284
|
+
data: {
|
|
3285
|
+
message: errorMessage,
|
|
3286
|
+
},
|
|
3287
|
+
})
|
|
3288
|
+
}
|
|
3289
|
+
successMessage="Validation failed"
|
|
3290
|
+
/>
|
|
3291
|
+
);
|
|
3292
|
+
}
|
|
3293
|
+
|
|
3294
|
+
return (
|
|
3295
|
+
<Box flexDirection="column">
|
|
3296
|
+
<ErrorMessage error="One or more flags are missing values. Please provide values for: " />
|
|
3297
|
+
{parseErrors.map((flag) => (
|
|
3298
|
+
<Text dimColor key={flag}>
|
|
3299
|
+
- {flag} {"<value>"}
|
|
3300
|
+
</Text>
|
|
3301
|
+
))}
|
|
3302
|
+
</Box>
|
|
3303
|
+
);
|
|
3304
|
+
}
|
|
2047
3305
|
|
|
2048
3306
|
// In non-interactive mode, skip telemetry prompt and default to disabled
|
|
2049
3307
|
useEffect(() => {
|
|
@@ -2056,9 +3314,11 @@ const App: React.FC<AppProps> = ({ command, flags }) => {
|
|
|
2056
3314
|
// Track command usage (must be before any conditional returns)
|
|
2057
3315
|
useEffect(() => {
|
|
2058
3316
|
if (group && !showTelemetryPrompt) {
|
|
2059
|
-
|
|
3317
|
+
const actionForTracking =
|
|
3318
|
+
group === "model" && normalizedAction !== action ? action || normalizedAction : normalizedAction;
|
|
3319
|
+
trackCommand(group, actionForTracking);
|
|
2060
3320
|
}
|
|
2061
|
-
}, [group, action, showTelemetryPrompt]);
|
|
3321
|
+
}, [group, action, normalizedAction, showTelemetryPrompt]);
|
|
2062
3322
|
|
|
2063
3323
|
// Show telemetry consent prompt on first run (but not for --help or --version, and only if interactive)
|
|
2064
3324
|
if (showTelemetryPrompt && isRawModeSupported && !flags.help && flags.version !== "true" && flags.v !== "true") {
|
|
@@ -2070,14 +3330,6 @@ const App: React.FC<AppProps> = ({ command, flags }) => {
|
|
|
2070
3330
|
return <Help />;
|
|
2071
3331
|
}
|
|
2072
3332
|
|
|
2073
|
-
// Chat command - Interactive agent
|
|
2074
|
-
if (group === "chat") {
|
|
2075
|
-
if (flags.help === "true" || action === "help") {
|
|
2076
|
-
return <Help context="chat" />;
|
|
2077
|
-
}
|
|
2078
|
-
return <ChatWrapper flags={flags} />;
|
|
2079
|
-
}
|
|
2080
|
-
|
|
2081
3333
|
// Auth commands
|
|
2082
3334
|
if (group === "auth") {
|
|
2083
3335
|
if (flags.help === "true" || !action || action === "help") {
|
|
@@ -2217,6 +3469,31 @@ const App: React.FC<AppProps> = ({ command, flags }) => {
|
|
|
2217
3469
|
);
|
|
2218
3470
|
}
|
|
2219
3471
|
|
|
3472
|
+
if (subAction === "dismiss-outlier" && rest[1]) {
|
|
3473
|
+
const dataset = parseDatasetRef(rest[1]);
|
|
3474
|
+
const fingerprint = flags["fingerprint"];
|
|
3475
|
+
if (!dataset) {
|
|
3476
|
+
return <ErrorMessage error={`Invalid dataset format: ${rest[1]}. Use name[:version] format (e.g., my-dataset or my-dataset:v1).`} />;
|
|
3477
|
+
}
|
|
3478
|
+
if (!fingerprint) {
|
|
3479
|
+
return (
|
|
3480
|
+
<ErrorMessage error="--fingerprint is required (from dataset analysis output)" />
|
|
3481
|
+
);
|
|
3482
|
+
}
|
|
3483
|
+
|
|
3484
|
+
return (
|
|
3485
|
+
<ApiCommand
|
|
3486
|
+
action={() =>
|
|
3487
|
+
api.dismissOutlier({
|
|
3488
|
+
dataset,
|
|
3489
|
+
fingerprint,
|
|
3490
|
+
})
|
|
3491
|
+
}
|
|
3492
|
+
successMessage={`Outlier dismissed for dataset ${rest[1]}`}
|
|
3493
|
+
/>
|
|
3494
|
+
);
|
|
3495
|
+
}
|
|
3496
|
+
|
|
2220
3497
|
return <Help context="dataset-edit" />;
|
|
2221
3498
|
}
|
|
2222
3499
|
|
|
@@ -2398,6 +3675,41 @@ const App: React.FC<AppProps> = ({ command, flags }) => {
|
|
|
2398
3675
|
/>
|
|
2399
3676
|
);
|
|
2400
3677
|
}
|
|
3678
|
+
if (action === "analyze-llm") {
|
|
3679
|
+
const datasetStr = rest[0];
|
|
3680
|
+
const taskType = flags["task-type"];
|
|
3681
|
+
const taskDescription = flags["description"] || flags["task-description"];
|
|
3682
|
+
const labels = parseCommaSeparated(flags["labels"]);
|
|
3683
|
+
|
|
3684
|
+
if (!datasetStr || !taskType) {
|
|
3685
|
+
return <Help context="dataset-analyze" />;
|
|
3686
|
+
}
|
|
3687
|
+
|
|
3688
|
+
if (!["ner", "classification", "generative"].includes(taskType)) {
|
|
3689
|
+
return (
|
|
3690
|
+
<ErrorMessage error="--task-type must be one of: ner, classification, generative" />
|
|
3691
|
+
);
|
|
3692
|
+
}
|
|
3693
|
+
|
|
3694
|
+
const dataset = parseDatasetRef(datasetStr);
|
|
3695
|
+
if (!dataset) {
|
|
3696
|
+
return <ErrorMessage error={`Invalid dataset format: ${datasetStr}. Use name:version format.`} />;
|
|
3697
|
+
}
|
|
3698
|
+
|
|
3699
|
+
return (
|
|
3700
|
+
<ApiCommand
|
|
3701
|
+
action={() =>
|
|
3702
|
+
api.analyzeDatasetLLM({
|
|
3703
|
+
task_type: taskType as "ner" | "classification" | "generative",
|
|
3704
|
+
dataset_name: dataset.name,
|
|
3705
|
+
dataset_version: dataset.version,
|
|
3706
|
+
...(taskDescription ? { task_description: taskDescription } : {}),
|
|
3707
|
+
...(labels.length ? { labels } : {}),
|
|
3708
|
+
})
|
|
3709
|
+
}
|
|
3710
|
+
/>
|
|
3711
|
+
);
|
|
3712
|
+
}
|
|
2401
3713
|
if (action === "analyze") {
|
|
2402
3714
|
const datasetStr = rest[0];
|
|
2403
3715
|
const taskType = flags["task-type"];
|
|
@@ -2427,6 +3739,131 @@ const App: React.FC<AppProps> = ({ command, flags }) => {
|
|
|
2427
3739
|
const domainDescription = flags["domain"];
|
|
2428
3740
|
const saveDataset = flags["save"]?.toLowerCase() === "true";
|
|
2429
3741
|
const datasetName = flags["name"];
|
|
3742
|
+
const quality = flags["quality"] as "light" | "medium" | "heavy" | undefined;
|
|
3743
|
+
const generationProfile = flags["generation-profile"] as
|
|
3744
|
+
| "auto"
|
|
3745
|
+
| "fast"
|
|
3746
|
+
| "balanced"
|
|
3747
|
+
| "quality"
|
|
3748
|
+
| undefined;
|
|
3749
|
+
const includeReasoningTrace =
|
|
3750
|
+
flags["reasoning-trace"] === undefined
|
|
3751
|
+
? undefined
|
|
3752
|
+
: flags["reasoning-trace"].toLowerCase() !== "false";
|
|
3753
|
+
const reasoningEffort = flags["reasoning-effort"] as
|
|
3754
|
+
| "low"
|
|
3755
|
+
| "medium"
|
|
3756
|
+
| "high"
|
|
3757
|
+
| undefined;
|
|
3758
|
+
const validGenerationProfiles = ["auto", "fast", "balanced", "quality"];
|
|
3759
|
+
if (generationProfile && !validGenerationProfiles.includes(generationProfile)) {
|
|
3760
|
+
return <ErrorMessage error="--generation-profile must be one of: auto, fast, balanced, quality" />;
|
|
3761
|
+
}
|
|
3762
|
+
const validReasoningEfforts = ["low", "medium", "high"];
|
|
3763
|
+
if (reasoningEffort && !validReasoningEfforts.includes(reasoningEffort)) {
|
|
3764
|
+
return <ErrorMessage error="--reasoning-effort must be one of: low, medium, high" />;
|
|
3765
|
+
}
|
|
3766
|
+
const multiplicatorArg = flags["multiplicator"];
|
|
3767
|
+
const useMetaFelix = flags["use-meta-felix"]
|
|
3768
|
+
? flags["use-meta-felix"].toLowerCase() !== "false"
|
|
3769
|
+
: undefined;
|
|
3770
|
+
const minCriteria = flags["min-criteria"] ? parseInt(flags["min-criteria"], 10) : undefined;
|
|
3771
|
+
if (flags["min-criteria"] && Number.isNaN(minCriteria)) {
|
|
3772
|
+
return <ErrorMessage error="--min-criteria must be a number" />;
|
|
3773
|
+
}
|
|
3774
|
+
const targetChoices = flags["target-choices"]
|
|
3775
|
+
? parseInt(flags["target-choices"], 10)
|
|
3776
|
+
: undefined;
|
|
3777
|
+
if (flags["target-choices"] && Number.isNaN(targetChoices)) {
|
|
3778
|
+
return <ErrorMessage error="--target-choices must be a number" />;
|
|
3779
|
+
}
|
|
3780
|
+
const projectId = flags["project-id"];
|
|
3781
|
+
const generationType = flags["type"] as "training" | "evaluation" | "split" | undefined;
|
|
3782
|
+
if (generationType && !["training", "evaluation", "split"].includes(generationType)) {
|
|
3783
|
+
return <ErrorMessage error="--type must be one of: training, evaluation, split" />;
|
|
3784
|
+
}
|
|
3785
|
+
const visibility = flags["visibility"] as "private" | "public" | undefined;
|
|
3786
|
+
if (visibility && !["private", "public"].includes(visibility)) {
|
|
3787
|
+
return <ErrorMessage error="--visibility must be private or public" />;
|
|
3788
|
+
}
|
|
3789
|
+
const splitRatioArg = flags["split-ratio"];
|
|
3790
|
+
const splitRatio =
|
|
3791
|
+
splitRatioArg && splitRatioArg.includes(":")
|
|
3792
|
+
? (() => {
|
|
3793
|
+
const [training, evaluation] = splitRatioArg.split(":").map((v) => parseFloat(v));
|
|
3794
|
+
if (Number.isNaN(training) || Number.isNaN(evaluation)) {
|
|
3795
|
+
return undefined;
|
|
3796
|
+
}
|
|
3797
|
+
return { training, evaluation };
|
|
3798
|
+
})()
|
|
3799
|
+
: splitRatioArg
|
|
3800
|
+
? (() => {
|
|
3801
|
+
try {
|
|
3802
|
+
const parsed = JSON.parse(splitRatioArg);
|
|
3803
|
+
return parsed;
|
|
3804
|
+
} catch {
|
|
3805
|
+
return undefined;
|
|
3806
|
+
}
|
|
3807
|
+
})()
|
|
3808
|
+
: undefined;
|
|
3809
|
+
const negativeRatio = flags["negative-ratio"]
|
|
3810
|
+
? parseFloat(flags["negative-ratio"])
|
|
3811
|
+
: undefined;
|
|
3812
|
+
if (flags["negative-ratio"] && Number.isNaN(negativeRatio)) {
|
|
3813
|
+
return <ErrorMessage error="--negative-ratio must be a number" />;
|
|
3814
|
+
}
|
|
3815
|
+
const classifiedExamplesArg = flags["classified-examples"];
|
|
3816
|
+
const qualityArg = flags["quality"];
|
|
3817
|
+
if (qualityArg && !["light", "medium", "heavy"].includes(qualityArg)) {
|
|
3818
|
+
return <ErrorMessage error="--quality must be light, medium, or heavy" />;
|
|
3819
|
+
}
|
|
3820
|
+
if (splitRatioArg && splitRatio === undefined) {
|
|
3821
|
+
return <ErrorMessage error="--split-ratio must be training:evaluation or a JSON object" />;
|
|
3822
|
+
}
|
|
3823
|
+
let parsedMultiplicator: Record<string, unknown> | undefined;
|
|
3824
|
+
if (multiplicatorArg) {
|
|
3825
|
+
try {
|
|
3826
|
+
const parsed = JSON.parse(multiplicatorArg);
|
|
3827
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
3828
|
+
return <ErrorMessage error="--multiplicator must be a valid JSON object" />;
|
|
3829
|
+
}
|
|
3830
|
+
parsedMultiplicator = parsed;
|
|
3831
|
+
} catch {
|
|
3832
|
+
return <ErrorMessage error="--multiplicator must be valid JSON" />;
|
|
3833
|
+
}
|
|
3834
|
+
}
|
|
3835
|
+
let classifiedExamples: Record<string, unknown>[] | undefined;
|
|
3836
|
+
if (classifiedExamplesArg) {
|
|
3837
|
+
try {
|
|
3838
|
+
const parsed = JSON.parse(classifiedExamplesArg);
|
|
3839
|
+
if (!Array.isArray(parsed)) {
|
|
3840
|
+
return <ErrorMessage error="--classified-examples must be a JSON array" />;
|
|
3841
|
+
}
|
|
3842
|
+
classifiedExamples = parsed as Record<string, unknown>[];
|
|
3843
|
+
} catch {
|
|
3844
|
+
return <ErrorMessage error="--classified-examples must be valid JSON" />;
|
|
3845
|
+
}
|
|
3846
|
+
}
|
|
3847
|
+
if (multiplicatorArg && parsedMultiplicator === undefined) {
|
|
3848
|
+
return <ErrorMessage error="--multiplicator must be a valid JSON object" />;
|
|
3849
|
+
}
|
|
3850
|
+
|
|
3851
|
+
const commonGenerationOptions = {
|
|
3852
|
+
quality,
|
|
3853
|
+
generation_profile: generationProfile,
|
|
3854
|
+
...(includeReasoningTrace !== undefined ? { include_reasoning_trace: includeReasoningTrace } : {}),
|
|
3855
|
+
...(reasoningEffort ? { reasoning_effort: reasoningEffort } : {}),
|
|
3856
|
+
...(multiplicatorArg ? { multiplicator: parsedMultiplicator } : {}),
|
|
3857
|
+
...(useMetaFelix !== undefined ? { use_meta_felix: useMetaFelix } : {}),
|
|
3858
|
+
...(minCriteria !== undefined ? { min_criteria: minCriteria } : {}),
|
|
3859
|
+
...(targetChoices !== undefined ? { target_choices: targetChoices } : {}),
|
|
3860
|
+
...(projectId ? { project_id: projectId } : {}),
|
|
3861
|
+
...(generationType ? { type: generationType } : {}),
|
|
3862
|
+
...(visibility ? { visibility } : {}),
|
|
3863
|
+
...(splitRatio ? { split_ratio: splitRatio } : {}),
|
|
3864
|
+
...(negativeRatio !== undefined ? { negative_ratio: negativeRatio } : {}),
|
|
3865
|
+
...(classifiedExamplesArg ? { classified_examples: classifiedExamples } : {}),
|
|
3866
|
+
};
|
|
2430
3867
|
|
|
2431
3868
|
if (subAction === "ner") {
|
|
2432
3869
|
const labels = flags["labels"]?.split(",");
|
|
@@ -2442,6 +3879,7 @@ const App: React.FC<AppProps> = ({ command, flags }) => {
|
|
|
2442
3879
|
domain_description: domainDescription,
|
|
2443
3880
|
save_dataset: saveDataset,
|
|
2444
3881
|
dataset_name: datasetName,
|
|
3882
|
+
...commonGenerationOptions,
|
|
2445
3883
|
})
|
|
2446
3884
|
}
|
|
2447
3885
|
datasetName={datasetName || "ner-dataset"}
|
|
@@ -2467,6 +3905,7 @@ const App: React.FC<AppProps> = ({ command, flags }) => {
|
|
|
2467
3905
|
multi_label: multiLabel,
|
|
2468
3906
|
save_dataset: saveDataset,
|
|
2469
3907
|
dataset_name: datasetName,
|
|
3908
|
+
...commonGenerationOptions,
|
|
2470
3909
|
})
|
|
2471
3910
|
}
|
|
2472
3911
|
datasetName={datasetName || "classification-dataset"}
|
|
@@ -2497,6 +3936,7 @@ const App: React.FC<AppProps> = ({ command, flags }) => {
|
|
|
2497
3936
|
num_examples: numExamples,
|
|
2498
3937
|
save_dataset: saveDataset,
|
|
2499
3938
|
dataset_name: datasetName,
|
|
3939
|
+
...commonGenerationOptions,
|
|
2500
3940
|
})
|
|
2501
3941
|
}
|
|
2502
3942
|
datasetName={datasetName || "custom-dataset"}
|
|
@@ -2506,12 +3946,74 @@ const App: React.FC<AppProps> = ({ command, flags }) => {
|
|
|
2506
3946
|
);
|
|
2507
3947
|
}
|
|
2508
3948
|
|
|
3949
|
+
if (subAction === "decoder") {
|
|
3950
|
+
const instruction = flags["instruction"];
|
|
3951
|
+
if (!domainDescription) {
|
|
3952
|
+
return <ErrorMessage error="--domain is required for decoder generation" />;
|
|
3953
|
+
}
|
|
3954
|
+
return (
|
|
3955
|
+
<GenerateCommand
|
|
3956
|
+
action={() =>
|
|
3957
|
+
api.generateDecoder({
|
|
3958
|
+
domain_description: domainDescription!,
|
|
3959
|
+
instruction,
|
|
3960
|
+
num_examples: numExamples,
|
|
3961
|
+
save_dataset: saveDataset,
|
|
3962
|
+
dataset_name: datasetName,
|
|
3963
|
+
...commonGenerationOptions,
|
|
3964
|
+
})
|
|
3965
|
+
}
|
|
3966
|
+
datasetName={datasetName || "decoder-dataset"}
|
|
3967
|
+
datasetType="custom"
|
|
3968
|
+
saveToRemote={saveDataset}
|
|
3969
|
+
/>
|
|
3970
|
+
);
|
|
3971
|
+
}
|
|
3972
|
+
|
|
2509
3973
|
return <Help context="dataset" />;
|
|
2510
3974
|
}
|
|
2511
3975
|
|
|
2512
3976
|
// Infer labels commands
|
|
2513
3977
|
if (action === "infer") {
|
|
2514
3978
|
const subAction = rest[0];
|
|
3979
|
+
if (subAction === "improve-prompt") {
|
|
3980
|
+
const prompt = flags["prompt"] || flags["domain"];
|
|
3981
|
+
if (!prompt) {
|
|
3982
|
+
return <ErrorMessage error="--prompt is required for infer improve-prompt" />;
|
|
3983
|
+
}
|
|
3984
|
+
const dataType = flags["data-type"];
|
|
3985
|
+
return (
|
|
3986
|
+
<ApiCommand
|
|
3987
|
+
action={() =>
|
|
3988
|
+
api.improvePrompt({
|
|
3989
|
+
prompt,
|
|
3990
|
+
...(dataType ? { data_type: dataType } : {}),
|
|
3991
|
+
})
|
|
3992
|
+
}
|
|
3993
|
+
/>
|
|
3994
|
+
);
|
|
3995
|
+
}
|
|
3996
|
+
|
|
3997
|
+
if (subAction === "infer-advanced" || subAction === "advanced") {
|
|
3998
|
+
const prompt = flags["prompt"] || flags["domain"];
|
|
3999
|
+
const dataType = flags["data-type"];
|
|
4000
|
+
const labels = parseCommaSeparated(flags["labels"]);
|
|
4001
|
+
if (!prompt) {
|
|
4002
|
+
return <ErrorMessage error="--prompt is required for dataset infer infer-advanced" />;
|
|
4003
|
+
}
|
|
4004
|
+
return (
|
|
4005
|
+
<ApiCommand
|
|
4006
|
+
action={() =>
|
|
4007
|
+
api.inferAdvanced({
|
|
4008
|
+
prompt,
|
|
4009
|
+
...(dataType ? { data_type: dataType } : {}),
|
|
4010
|
+
...(labels.length > 0 ? { labels } : {}),
|
|
4011
|
+
})
|
|
4012
|
+
}
|
|
4013
|
+
/>
|
|
4014
|
+
);
|
|
4015
|
+
}
|
|
4016
|
+
|
|
2515
4017
|
const domainDescription = flags["domain"];
|
|
2516
4018
|
|
|
2517
4019
|
if (!domainDescription) {
|
|
@@ -2545,6 +4047,128 @@ const App: React.FC<AppProps> = ({ command, flags }) => {
|
|
|
2545
4047
|
return <Help context="dataset" />;
|
|
2546
4048
|
}
|
|
2547
4049
|
|
|
4050
|
+
if (action === "label-existing") {
|
|
4051
|
+
const subAction = rest[0];
|
|
4052
|
+
const labels = parseCommaSeparated(flags["labels"]);
|
|
4053
|
+
const inputsArg = flags["inputs"];
|
|
4054
|
+
const datasetName = flags["name"];
|
|
4055
|
+
const saveDataset = flags["save"]?.toLowerCase() === "true";
|
|
4056
|
+
const domainDescription = flags["domain"];
|
|
4057
|
+
const projectId = flags["project-id"];
|
|
4058
|
+
if (!inputsArg) {
|
|
4059
|
+
return <ErrorMessage error="--inputs is required for label-existing commands" />;
|
|
4060
|
+
}
|
|
4061
|
+
if (saveDataset && !datasetName) {
|
|
4062
|
+
return <ErrorMessage error="--name is required when --save=true for label-existing" />;
|
|
4063
|
+
}
|
|
4064
|
+
|
|
4065
|
+
let inputs: unknown;
|
|
4066
|
+
try {
|
|
4067
|
+
inputs = JSON.parse(inputsArg);
|
|
4068
|
+
} catch {
|
|
4069
|
+
return <ErrorMessage error="--inputs must be valid JSON" />;
|
|
4070
|
+
}
|
|
4071
|
+
|
|
4072
|
+
if (subAction === "ner" || subAction === "classification") {
|
|
4073
|
+
if (!labels || labels.length === 0) {
|
|
4074
|
+
return <ErrorMessage error="--labels is required for label-existing ner|classification" />;
|
|
4075
|
+
}
|
|
4076
|
+
if (
|
|
4077
|
+
!Array.isArray(inputs) ||
|
|
4078
|
+
inputs.length === 0 ||
|
|
4079
|
+
!inputs.every((item) => typeof item === "string")
|
|
4080
|
+
) {
|
|
4081
|
+
return <ErrorMessage error="--inputs must be a JSON array of strings for ner/classification" />;
|
|
4082
|
+
}
|
|
4083
|
+
const common = { labels, inputs: inputs as string[], dataset_name: datasetName };
|
|
4084
|
+
if (subAction === "ner") {
|
|
4085
|
+
return (
|
|
4086
|
+
<ApiCommand
|
|
4087
|
+
action={() =>
|
|
4088
|
+
api.labelExistingNER({
|
|
4089
|
+
...common,
|
|
4090
|
+
domain_description: domainDescription,
|
|
4091
|
+
save_dataset: saveDataset,
|
|
4092
|
+
project_id: projectId,
|
|
4093
|
+
})
|
|
4094
|
+
}
|
|
4095
|
+
/>
|
|
4096
|
+
);
|
|
4097
|
+
}
|
|
4098
|
+
return (
|
|
4099
|
+
<ApiCommand
|
|
4100
|
+
action={() =>
|
|
4101
|
+
api.labelExistingClassification({
|
|
4102
|
+
...common,
|
|
4103
|
+
domain_description: domainDescription,
|
|
4104
|
+
save_dataset: saveDataset,
|
|
4105
|
+
project_id: projectId,
|
|
4106
|
+
})
|
|
4107
|
+
}
|
|
4108
|
+
/>
|
|
4109
|
+
);
|
|
4110
|
+
}
|
|
4111
|
+
|
|
4112
|
+
if (subAction === "fields") {
|
|
4113
|
+
const inputFieldsArg = flags["input-fields"];
|
|
4114
|
+
const outputFieldsArg = flags["output-fields"];
|
|
4115
|
+
if (!inputFieldsArg || !outputFieldsArg) {
|
|
4116
|
+
return <ErrorMessage error="--input-fields and --output-fields are required for fields labeling" />;
|
|
4117
|
+
}
|
|
4118
|
+
let inputFields: unknown;
|
|
4119
|
+
let outputFields: unknown;
|
|
4120
|
+
try {
|
|
4121
|
+
inputFields = JSON.parse(inputFieldsArg);
|
|
4122
|
+
outputFields = JSON.parse(outputFieldsArg);
|
|
4123
|
+
} catch {
|
|
4124
|
+
return <ErrorMessage error="--input-fields and --output-fields must be valid JSON" />;
|
|
4125
|
+
}
|
|
4126
|
+
if (
|
|
4127
|
+
!Array.isArray(inputFields) ||
|
|
4128
|
+
!Array.isArray(outputFields) ||
|
|
4129
|
+
inputFields.length === 0 ||
|
|
4130
|
+
outputFields.length === 0
|
|
4131
|
+
) {
|
|
4132
|
+
return (
|
|
4133
|
+
<ErrorMessage error="--input-fields and --output-fields must be non-empty arrays" />
|
|
4134
|
+
);
|
|
4135
|
+
}
|
|
4136
|
+
const validInputFields = inputFields.every(
|
|
4137
|
+
(field) => field && typeof field === "object" && !Array.isArray(field)
|
|
4138
|
+
);
|
|
4139
|
+
const validOutputFields = outputFields.every(
|
|
4140
|
+
(field) => field && typeof field === "object" && !Array.isArray(field)
|
|
4141
|
+
);
|
|
4142
|
+
if (!validInputFields || !validOutputFields) {
|
|
4143
|
+
return <ErrorMessage error="--input-fields and --output-fields must be arrays of objects" />;
|
|
4144
|
+
}
|
|
4145
|
+
if (
|
|
4146
|
+
!Array.isArray(inputs) ||
|
|
4147
|
+
inputs.length === 0 ||
|
|
4148
|
+
!inputs.every((item) => item && typeof item === "object" && !Array.isArray(item))
|
|
4149
|
+
) {
|
|
4150
|
+
return <ErrorMessage error="--inputs must be a JSON array of objects for fields" />;
|
|
4151
|
+
}
|
|
4152
|
+
return (
|
|
4153
|
+
<ApiCommand
|
|
4154
|
+
action={() =>
|
|
4155
|
+
api.labelExistingFields({
|
|
4156
|
+
input_fields: inputFields as api.RecordField[],
|
|
4157
|
+
output_fields: outputFields as api.RecordField[],
|
|
4158
|
+
inputs: inputs as Record<string, unknown>[],
|
|
4159
|
+
dataset_name: datasetName,
|
|
4160
|
+
save_dataset: saveDataset,
|
|
4161
|
+
domain_description: domainDescription,
|
|
4162
|
+
project_id: projectId,
|
|
4163
|
+
})
|
|
4164
|
+
}
|
|
4165
|
+
/>
|
|
4166
|
+
);
|
|
4167
|
+
}
|
|
4168
|
+
|
|
4169
|
+
return <Help context="dataset" />;
|
|
4170
|
+
}
|
|
4171
|
+
|
|
2548
4172
|
return <Help context="dataset" />;
|
|
2549
4173
|
}
|
|
2550
4174
|
|
|
@@ -2602,125 +4226,558 @@ const App: React.FC<AppProps> = ({ command, flags }) => {
|
|
|
2602
4226
|
return <Help context="job" />;
|
|
2603
4227
|
}
|
|
2604
4228
|
|
|
2605
|
-
//
|
|
2606
|
-
if (group === "
|
|
4229
|
+
// Inference commands
|
|
4230
|
+
if (group === "inference") {
|
|
2607
4231
|
if (flags.help === "true" || !action || action === "help") {
|
|
2608
|
-
return <Help context="
|
|
4232
|
+
return <Help context="inference" />;
|
|
2609
4233
|
}
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
4234
|
+
|
|
4235
|
+
if (action === "base-models" || action === "models" || action === "list") {
|
|
4236
|
+
return <ApiCommand action={api.listBaseModels} />;
|
|
4237
|
+
}
|
|
4238
|
+
|
|
4239
|
+
if (action === "encoder") {
|
|
4240
|
+
const rawModelId = rest[0];
|
|
4241
|
+
if (!rawModelId) {
|
|
4242
|
+
return (
|
|
4243
|
+
<ErrorMessage error="Model ID required. Usage: inference encoder <model-id> --text <text> --labels <labels>" />
|
|
4244
|
+
);
|
|
2614
4245
|
}
|
|
2615
|
-
|
|
2616
|
-
|
|
4246
|
+
const modelId = normalizeModelId(rawModelId);
|
|
4247
|
+
const text = flags["text"];
|
|
4248
|
+
if (!text) {
|
|
4249
|
+
return <ErrorMessage error="--text is required for encoder inference" />;
|
|
2617
4250
|
}
|
|
2618
|
-
|
|
2619
|
-
|
|
4251
|
+
|
|
4252
|
+
const task = (flags["task"] || "extract_entities") as
|
|
4253
|
+
| "extract_entities"
|
|
4254
|
+
| "classify_text"
|
|
4255
|
+
| "extract_json"
|
|
4256
|
+
| "schema";
|
|
4257
|
+
if (!["extract_entities", "classify_text", "extract_json", "schema"].includes(task)) {
|
|
4258
|
+
return (
|
|
4259
|
+
<ErrorMessage error="--task must be one of: extract_entities, classify_text, extract_json, schema" />
|
|
4260
|
+
);
|
|
2620
4261
|
}
|
|
2621
|
-
|
|
2622
|
-
|
|
4262
|
+
|
|
4263
|
+
const labels = parseCommaSeparated(flags["labels"]);
|
|
4264
|
+
const schemaStr = flags["schema"];
|
|
4265
|
+
let schema: string[] | Record<string, unknown> | null = null;
|
|
4266
|
+
|
|
4267
|
+
if (schemaStr) {
|
|
4268
|
+
try {
|
|
4269
|
+
const parsed = JSON.parse(schemaStr) as unknown;
|
|
4270
|
+
if (Array.isArray(parsed)) {
|
|
4271
|
+
if (!parsed.every((item) => typeof item === "string")) {
|
|
4272
|
+
return (
|
|
4273
|
+
<ErrorMessage error="--schema JSON array must contain only strings" />
|
|
4274
|
+
);
|
|
4275
|
+
}
|
|
4276
|
+
schema = parsed;
|
|
4277
|
+
} else if (parsed && typeof parsed === "object") {
|
|
4278
|
+
schema = parsed as Record<string, unknown>;
|
|
4279
|
+
} else {
|
|
4280
|
+
return (
|
|
4281
|
+
<ErrorMessage error="--schema must be a JSON object or array of strings" />
|
|
4282
|
+
);
|
|
4283
|
+
}
|
|
4284
|
+
} catch {
|
|
4285
|
+
return <ErrorMessage error="--schema must be valid JSON" />;
|
|
4286
|
+
}
|
|
4287
|
+
} else if (labels.length > 0) {
|
|
4288
|
+
schema = labels;
|
|
4289
|
+
}
|
|
4290
|
+
|
|
4291
|
+
if (!schema) {
|
|
4292
|
+
return <ErrorMessage error="Provide --labels or --schema for encoder inference" />;
|
|
4293
|
+
}
|
|
4294
|
+
|
|
4295
|
+
const threshold = flags["threshold"] ? parseFloat(flags["threshold"]) : 0.5;
|
|
4296
|
+
if (Number.isNaN(threshold) || threshold < 0 || threshold > 1) {
|
|
4297
|
+
return <ErrorMessage error="--threshold must be a number between 0 and 1" />;
|
|
4298
|
+
}
|
|
4299
|
+
|
|
4300
|
+
const includeConfidence =
|
|
4301
|
+
flags["include-confidence"] === undefined ||
|
|
4302
|
+
flags["include-confidence"].toLowerCase() !== "false";
|
|
4303
|
+
const includeSpans = flags["include-spans"]?.toLowerCase() === "true";
|
|
4304
|
+
const formatResults =
|
|
4305
|
+
flags["format-results"] === undefined ||
|
|
4306
|
+
flags["format-results"].toLowerCase() !== "false";
|
|
4307
|
+
const projectId = flags["project-id"];
|
|
4308
|
+
|
|
4309
|
+
return (
|
|
4310
|
+
<ApiCommand
|
|
4311
|
+
action={() =>
|
|
4312
|
+
api.runInference({
|
|
4313
|
+
model_id: modelId,
|
|
4314
|
+
task,
|
|
4315
|
+
text,
|
|
4316
|
+
schema,
|
|
4317
|
+
threshold,
|
|
4318
|
+
include_confidence: includeConfidence,
|
|
4319
|
+
include_spans: includeSpans,
|
|
4320
|
+
format_results: formatResults,
|
|
4321
|
+
...(projectId ? { project_id: projectId } : {}),
|
|
4322
|
+
})
|
|
4323
|
+
}
|
|
4324
|
+
/>
|
|
4325
|
+
);
|
|
2623
4326
|
}
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
4327
|
+
|
|
4328
|
+
if (action === "decoder") {
|
|
4329
|
+
const modelId = rest[0];
|
|
4330
|
+
if (!modelId) {
|
|
4331
|
+
return (
|
|
4332
|
+
<ErrorMessage error="Model ID required. Usage: inference decoder <model-id> --prompt <text>" />
|
|
4333
|
+
);
|
|
4334
|
+
}
|
|
4335
|
+
const normalizedModelId = normalizeModelId(modelId);
|
|
4336
|
+
const prompt = flags["prompt"];
|
|
4337
|
+
if (!prompt) {
|
|
4338
|
+
return <ErrorMessage error="--prompt is required for decoder inference" />;
|
|
4339
|
+
}
|
|
4340
|
+
const systemMsg = flags["system"];
|
|
4341
|
+
const maxTokens = flags["max-tokens"] ? parseInt(flags["max-tokens"], 10) : 256;
|
|
4342
|
+
if (Number.isNaN(maxTokens) || maxTokens < 1) {
|
|
4343
|
+
return <ErrorMessage error="--max-tokens must be a positive integer" />;
|
|
2627
4344
|
}
|
|
2628
|
-
const
|
|
2629
|
-
if (
|
|
4345
|
+
const temperature = flags["temperature"] ? parseFloat(flags["temperature"]) : 0.7;
|
|
4346
|
+
if (Number.isNaN(temperature) || temperature < 0 || temperature > 2) {
|
|
4347
|
+
return <ErrorMessage error="--temperature must be a number between 0 and 2" />;
|
|
4348
|
+
}
|
|
4349
|
+
const topP = flags["top-p"] ? parseFloat(flags["top-p"]) : undefined;
|
|
4350
|
+
if (topP !== undefined && (Number.isNaN(topP) || topP < 0 || topP > 1)) {
|
|
4351
|
+
return <ErrorMessage error="--top-p must be a number between 0 and 1" />;
|
|
4352
|
+
}
|
|
4353
|
+
const includeReasoningTrace =
|
|
4354
|
+
flags["reasoning-trace"] !== undefined &&
|
|
4355
|
+
flags["reasoning-trace"].toLowerCase() !== "false";
|
|
4356
|
+
const projectId = flags["project-id"];
|
|
4357
|
+
|
|
4358
|
+
return (
|
|
4359
|
+
<ModelGenerateCommand
|
|
4360
|
+
modelId={normalizedModelId}
|
|
4361
|
+
prompt={prompt}
|
|
4362
|
+
systemMsg={systemMsg}
|
|
4363
|
+
maxTokens={maxTokens}
|
|
4364
|
+
temperature={temperature}
|
|
4365
|
+
topP={topP}
|
|
4366
|
+
includeReasoningTrace={includeReasoningTrace}
|
|
4367
|
+
projectId={projectId}
|
|
4368
|
+
/>
|
|
4369
|
+
);
|
|
4370
|
+
}
|
|
4371
|
+
|
|
4372
|
+
if (action === "completions") {
|
|
4373
|
+
const rawModelId = rest[0];
|
|
4374
|
+
if (!rawModelId) {
|
|
2630
4375
|
return (
|
|
2631
|
-
<
|
|
2632
|
-
<ErrorMessage error="Invalid job ID: must be full UUID (36 characters)" />
|
|
2633
|
-
<Text dimColor> Provided: {jobId} ({jobId.length} characters)</Text>
|
|
2634
|
-
<Text dimColor> Tip: Use 'pioneer model list' to see full job IDs</Text>
|
|
2635
|
-
</Box>
|
|
4376
|
+
<ErrorMessage error="Model ID required. Usage: inference completions <model-id> --prompt <text>" />
|
|
2636
4377
|
);
|
|
2637
4378
|
}
|
|
4379
|
+
const modelId = normalizeModelId(rawModelId);
|
|
4380
|
+
const prompt = flags["prompt"];
|
|
4381
|
+
if (!prompt) {
|
|
4382
|
+
return <ErrorMessage error="--prompt is required for text completions" />;
|
|
4383
|
+
}
|
|
4384
|
+
|
|
4385
|
+
const systemMsg = flags["system"];
|
|
4386
|
+
const maxTokens = flags["max-tokens"] ? parseInt(flags["max-tokens"], 10) : 256;
|
|
4387
|
+
if (Number.isNaN(maxTokens) || maxTokens < 1) {
|
|
4388
|
+
return <ErrorMessage error="--max-tokens must be a positive integer" />;
|
|
4389
|
+
}
|
|
4390
|
+
const temperature = flags["temperature"] ? parseFloat(flags["temperature"]) : 0.7;
|
|
4391
|
+
if (Number.isNaN(temperature) || temperature < 0 || temperature > 2) {
|
|
4392
|
+
return <ErrorMessage error="--temperature must be a number between 0 and 2" />;
|
|
4393
|
+
}
|
|
4394
|
+
const topP = flags["top-p"] ? parseFloat(flags["top-p"]) : undefined;
|
|
4395
|
+
if (topP !== undefined && (Number.isNaN(topP) || topP < 0 || topP > 1)) {
|
|
4396
|
+
return <ErrorMessage error="--top-p must be a number between 0 and 1" />;
|
|
4397
|
+
}
|
|
4398
|
+
const stopValues = parseCommaSeparated(flags["stop"]);
|
|
4399
|
+
const stop =
|
|
4400
|
+
stopValues.length === 0 ? undefined : stopValues.length === 1 ? stopValues[0] : stopValues;
|
|
4401
|
+
const echo = flags["echo"]?.toLowerCase() === "true";
|
|
4402
|
+
const provider = flags["provider"];
|
|
4403
|
+
|
|
4404
|
+
const extraBody: Record<string, unknown> = {};
|
|
4405
|
+
if (topP !== undefined) extraBody.top_p = topP;
|
|
4406
|
+
if (provider) extraBody.provider = provider;
|
|
4407
|
+
|
|
2638
4408
|
return (
|
|
2639
4409
|
<ApiCommand
|
|
2640
|
-
action={() =>
|
|
2641
|
-
|
|
4410
|
+
action={() =>
|
|
4411
|
+
api.runTextCompletion({
|
|
4412
|
+
model: modelId,
|
|
4413
|
+
prompt: buildTextCompletionPrompt(prompt, systemMsg),
|
|
4414
|
+
max_tokens: maxTokens,
|
|
4415
|
+
temperature,
|
|
4416
|
+
...(stop !== undefined ? { stop } : {}),
|
|
4417
|
+
...(echo ? { echo: true } : {}),
|
|
4418
|
+
...(Object.keys(extraBody).length > 0 ? { extra_body: extraBody } : {}),
|
|
4419
|
+
})
|
|
4420
|
+
}
|
|
2642
4421
|
/>
|
|
2643
4422
|
);
|
|
2644
4423
|
}
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
4424
|
+
|
|
4425
|
+
return <Help context="inference" />;
|
|
4426
|
+
}
|
|
4427
|
+
|
|
4428
|
+
// Model commands
|
|
4429
|
+
if (group === "model") {
|
|
4430
|
+
if (flags.help === "true" || !action || action === "help") {
|
|
4431
|
+
return <Help context="model" />;
|
|
4432
|
+
}
|
|
4433
|
+
|
|
4434
|
+
if (normalizedAction === "endpoints") {
|
|
4435
|
+
const endpointAction = rest[0];
|
|
4436
|
+
const endpointArgs = rest.slice(1);
|
|
4437
|
+
|
|
4438
|
+
if (flags.help === "true" || !endpointAction || endpointAction === "help") {
|
|
4439
|
+
return <Help context="model-endpoints" />;
|
|
2648
4440
|
}
|
|
2649
|
-
|
|
2650
|
-
if (
|
|
4441
|
+
|
|
4442
|
+
if (endpointAction === "create") {
|
|
4443
|
+
const name = flags["name"];
|
|
4444
|
+
const icon = flags["icon"];
|
|
4445
|
+
const repo = flags["repo"];
|
|
4446
|
+
const description = flags["description"];
|
|
4447
|
+
const modelId = flags["model"] || "";
|
|
4448
|
+
const exampleStr = flags["example"];
|
|
4449
|
+
|
|
4450
|
+
if (flags["model-id"]) {
|
|
4451
|
+
return (
|
|
4452
|
+
<ErrorMessage error="Use --model to specify the base model reference. --model-id is deprecated." />
|
|
4453
|
+
);
|
|
4454
|
+
}
|
|
4455
|
+
|
|
4456
|
+
if (flags["base-model"] || flags["active-model-id"]) {
|
|
4457
|
+
return (
|
|
4458
|
+
<ErrorMessage error="Use --model to specify the model reference. --base-model and --active-model-id are no longer supported." />
|
|
4459
|
+
);
|
|
4460
|
+
}
|
|
4461
|
+
|
|
4462
|
+
if (!modelId) {
|
|
4463
|
+
const parsedExample = parseProjectExample(exampleStr);
|
|
4464
|
+
if (parsedExample.error) {
|
|
4465
|
+
return <ErrorMessage error={parsedExample.error} />;
|
|
4466
|
+
}
|
|
4467
|
+
return (
|
|
4468
|
+
<ModelCreateInteractive
|
|
4469
|
+
name={name}
|
|
4470
|
+
icon={icon}
|
|
4471
|
+
repo={repo}
|
|
4472
|
+
description={description}
|
|
4473
|
+
example={parsedExample.value}
|
|
4474
|
+
/>
|
|
4475
|
+
);
|
|
4476
|
+
}
|
|
4477
|
+
|
|
4478
|
+
const parsedExample = parseProjectExample(exampleStr);
|
|
4479
|
+
if (parsedExample.error) {
|
|
4480
|
+
return <ErrorMessage error={parsedExample.error} />;
|
|
4481
|
+
}
|
|
4482
|
+
|
|
2651
4483
|
return (
|
|
2652
|
-
<
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
4484
|
+
<ApiCommand
|
|
4485
|
+
action={() =>
|
|
4486
|
+
api.createProject({
|
|
4487
|
+
name: name ?? modelId,
|
|
4488
|
+
...(icon ? { icon } : {}),
|
|
4489
|
+
...(repo ? { repo } : {}),
|
|
4490
|
+
...(description ? { description } : {}),
|
|
4491
|
+
...(modelId ? { active_model_id: modelId } : {}),
|
|
4492
|
+
...(modelId ? { selected_model_id: modelId } : {}),
|
|
4493
|
+
...(parsedExample.value ? { example: parsedExample.value } : {}),
|
|
4494
|
+
})
|
|
4495
|
+
}
|
|
4496
|
+
successMessage="Model entry created"
|
|
4497
|
+
/>
|
|
2657
4498
|
);
|
|
2658
4499
|
}
|
|
2659
|
-
return <ApiCommand action={() => api.downloadModel(jobId)} />;
|
|
2660
|
-
}
|
|
2661
|
-
// Model upload command
|
|
2662
|
-
if (action === "upload") {
|
|
2663
|
-
const destination = flags["to"];
|
|
2664
4500
|
|
|
2665
|
-
|
|
2666
|
-
|
|
4501
|
+
if (endpointAction === "list") {
|
|
4502
|
+
return <ModelListCommand filter="registered" />;
|
|
4503
|
+
}
|
|
4504
|
+
|
|
4505
|
+
if (endpointAction === "get") {
|
|
4506
|
+
const modelId = endpointArgs[0];
|
|
4507
|
+
if (!modelId) {
|
|
4508
|
+
return <ErrorMessage error="Model ID required: model endpoints get <model-id>" />;
|
|
4509
|
+
}
|
|
4510
|
+
return <ApiCommand action={() => api.getProject(modelId)} />;
|
|
4511
|
+
}
|
|
4512
|
+
|
|
4513
|
+
if (endpointAction === "update") {
|
|
4514
|
+
const modelId = endpointArgs[0];
|
|
4515
|
+
if (!modelId) {
|
|
4516
|
+
return <ErrorMessage error="Model ID required: model endpoints update <model-id>" />;
|
|
4517
|
+
}
|
|
4518
|
+
|
|
4519
|
+
const name = flags["name"];
|
|
4520
|
+
const icon = flags["icon"];
|
|
4521
|
+
const repo = flags["repo"];
|
|
4522
|
+
const description = flags["description"];
|
|
4523
|
+
const selectedModelId = flags["model-id"];
|
|
4524
|
+
|
|
4525
|
+
if (!name && !icon && !repo && !description && !selectedModelId) {
|
|
4526
|
+
return (
|
|
4527
|
+
<ErrorMessage error="Provide at least one field to update: --name, --icon, --repo, --description, or --model-id" />
|
|
4528
|
+
);
|
|
4529
|
+
}
|
|
4530
|
+
|
|
2667
4531
|
return (
|
|
2668
|
-
<
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
4532
|
+
<ApiCommand
|
|
4533
|
+
action={() =>
|
|
4534
|
+
api.updateProject(modelId, {
|
|
4535
|
+
...(name ? { name } : {}),
|
|
4536
|
+
...(icon ? { icon } : {}),
|
|
4537
|
+
...(repo ? { repo } : {}),
|
|
4538
|
+
...(description ? { description } : {}),
|
|
4539
|
+
...(selectedModelId ? { selected_model_id: selectedModelId } : {}),
|
|
4540
|
+
})
|
|
4541
|
+
}
|
|
4542
|
+
successMessage="Model updated"
|
|
4543
|
+
/>
|
|
2676
4544
|
);
|
|
2677
4545
|
}
|
|
2678
4546
|
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
if (!
|
|
2682
|
-
return <ErrorMessage error="
|
|
4547
|
+
if (endpointAction === "delete") {
|
|
4548
|
+
const modelId = endpointArgs[0];
|
|
4549
|
+
if (!modelId) {
|
|
4550
|
+
return <ErrorMessage error="Model ID required: model endpoints delete <model-id>" />;
|
|
2683
4551
|
}
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
4552
|
+
return (
|
|
4553
|
+
<ApiCommand
|
|
4554
|
+
action={() => api.deleteProject(modelId)}
|
|
4555
|
+
successMessage={`Model ${modelId} deleted`}
|
|
4556
|
+
/>
|
|
4557
|
+
);
|
|
4558
|
+
}
|
|
2688
4559
|
|
|
2689
|
-
|
|
2690
|
-
|
|
4560
|
+
if (endpointAction === "dataset-count" || endpointAction === "count") {
|
|
4561
|
+
const modelId = endpointArgs[0];
|
|
4562
|
+
if (!modelId) {
|
|
4563
|
+
return <ErrorMessage error="Model ID required: model endpoints dataset-count <model-id>" />;
|
|
2691
4564
|
}
|
|
4565
|
+
return <ApiCommand action={() => api.getProjectDatasetCount(modelId)} />;
|
|
4566
|
+
}
|
|
2692
4567
|
|
|
2693
|
-
|
|
2694
|
-
|
|
4568
|
+
if (endpointAction === "quality-metrics" || endpointAction === "quality") {
|
|
4569
|
+
const modelId = endpointArgs[0];
|
|
4570
|
+
if (!modelId) {
|
|
4571
|
+
return <ErrorMessage error="Model ID required: model endpoints quality-metrics <model-id>" />;
|
|
4572
|
+
}
|
|
4573
|
+
return <ApiCommand action={() => api.getProjectQualityMetrics(modelId)} />;
|
|
4574
|
+
}
|
|
4575
|
+
|
|
4576
|
+
if (endpointAction === "deploy") {
|
|
4577
|
+
const modelId = endpointArgs[0];
|
|
4578
|
+
const jobId = flags["job"];
|
|
4579
|
+
|
|
4580
|
+
if (!modelId) {
|
|
4581
|
+
return <ErrorMessage error="Model ID required: model endpoints deploy <model-id> --job <training-job-id>" />;
|
|
4582
|
+
}
|
|
4583
|
+
if (!jobId) {
|
|
4584
|
+
return <ErrorMessage error="Training job ID required: model endpoints deploy <model-id> --job <training-job-id>" />;
|
|
4585
|
+
}
|
|
4586
|
+
if (jobId.length !== 36) {
|
|
2695
4587
|
return (
|
|
2696
4588
|
<Box flexDirection="column">
|
|
2697
|
-
<ErrorMessage error="
|
|
2698
|
-
<Text> </Text>
|
|
2699
|
-
<Text>
|
|
2700
|
-
<Text color="cyan"> pioneer auth hf</Text>
|
|
2701
|
-
<Text> </Text>
|
|
2702
|
-
<Text dimColor>Get a token at: https://huggingface.co/settings/tokens</Text>
|
|
4589
|
+
<ErrorMessage error="Invalid job ID: must be full UUID (36 characters)" />
|
|
4590
|
+
<Text dimColor> Provided: {jobId} ({jobId.length} characters)</Text>
|
|
4591
|
+
<Text dimColor> Tip: Use 'pioneer model artifacts list' and 'pioneer model artifacts trained' to see full job IDs</Text>
|
|
2703
4592
|
</Box>
|
|
2704
4593
|
);
|
|
2705
4594
|
}
|
|
2706
4595
|
|
|
4596
|
+
const reason = flags["reason"];
|
|
4597
|
+
|
|
2707
4598
|
return (
|
|
2708
4599
|
<ApiCommand
|
|
2709
4600
|
action={() =>
|
|
2710
|
-
api.
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
private: isPrivate,
|
|
4601
|
+
api.deployTrainingJobToProject(modelId, {
|
|
4602
|
+
training_job_id: jobId,
|
|
4603
|
+
...(reason ? { reason } : {}),
|
|
2714
4604
|
})
|
|
2715
4605
|
}
|
|
2716
|
-
successMessage={`
|
|
4606
|
+
successMessage={`Deployment initiated for project ${modelId} from job ${jobId}`}
|
|
2717
4607
|
/>
|
|
2718
4608
|
);
|
|
2719
4609
|
}
|
|
2720
4610
|
|
|
2721
|
-
|
|
4611
|
+
if (endpointAction === "rollback") {
|
|
4612
|
+
const modelId = endpointArgs[0];
|
|
4613
|
+
const deploymentId = endpointArgs[1];
|
|
4614
|
+
|
|
4615
|
+
if (!modelId) {
|
|
4616
|
+
return <ErrorMessage error="Model ID required: model endpoints rollback <model-id> <deployment-id>" />;
|
|
4617
|
+
}
|
|
4618
|
+
if (!deploymentId) {
|
|
4619
|
+
return (
|
|
4620
|
+
<ErrorMessage error="Deployment ID required: model endpoints rollback <model-id> <deployment-id>" />
|
|
4621
|
+
);
|
|
4622
|
+
}
|
|
4623
|
+
if (deploymentId.length !== 36) {
|
|
4624
|
+
return (
|
|
4625
|
+
<Box flexDirection="column">
|
|
4626
|
+
<ErrorMessage error="Invalid deployment ID: must be full UUID (36 characters)" />
|
|
4627
|
+
<Text dimColor> Provided: {deploymentId} ({deploymentId.length} characters)</Text>
|
|
4628
|
+
</Box>
|
|
4629
|
+
);
|
|
4630
|
+
}
|
|
4631
|
+
|
|
4632
|
+
return (
|
|
4633
|
+
<ApiCommand
|
|
4634
|
+
action={() => api.rollbackProjectDeployment(modelId, deploymentId)}
|
|
4635
|
+
successMessage={`Rollback initiated for endpoint ${modelId} using deployment ${deploymentId}`}
|
|
4636
|
+
/>
|
|
4637
|
+
);
|
|
4638
|
+
}
|
|
4639
|
+
|
|
4640
|
+
return <Help context="model-endpoints" />;
|
|
4641
|
+
}
|
|
4642
|
+
|
|
4643
|
+
if (normalizedAction === "artifacts") {
|
|
4644
|
+
const artifactsAction = rest[0];
|
|
4645
|
+
const artifactArgs = rest.slice(1);
|
|
4646
|
+
|
|
4647
|
+
if (flags.help === "true" || !artifactsAction || artifactsAction === "help") {
|
|
4648
|
+
return <Help context="model-artifacts" />;
|
|
4649
|
+
}
|
|
4650
|
+
|
|
4651
|
+
if (artifactsAction === "list") {
|
|
4652
|
+
return <ModelListCommand filter="artifacts" />;
|
|
4653
|
+
}
|
|
4654
|
+
|
|
4655
|
+
if (artifactsAction === "trained") {
|
|
4656
|
+
return <ModelListCommand filter="trained" />;
|
|
4657
|
+
}
|
|
4658
|
+
|
|
4659
|
+
if (artifactsAction === "deployed") {
|
|
4660
|
+
return <ModelListCommand filter="deployed" />;
|
|
4661
|
+
}
|
|
4662
|
+
|
|
4663
|
+
if (artifactsAction === "download") {
|
|
4664
|
+
if (!artifactArgs[0]) {
|
|
4665
|
+
return <ErrorMessage error="Job ID required: model artifacts download <job-id>" />;
|
|
4666
|
+
}
|
|
4667
|
+
const jobId = artifactArgs[0];
|
|
4668
|
+
if (jobId.length !== 36) {
|
|
4669
|
+
return (
|
|
4670
|
+
<Box flexDirection="column">
|
|
4671
|
+
<ErrorMessage error="Invalid job ID: must be full UUID (36 characters)" />
|
|
4672
|
+
<Text dimColor> Provided: {jobId} ({jobId.length} characters)</Text>
|
|
4673
|
+
<Text dimColor> Tip: Use 'pioneer model artifacts trained' or 'pioneer model artifacts deployed' to see full job IDs</Text>
|
|
4674
|
+
</Box>
|
|
4675
|
+
);
|
|
4676
|
+
}
|
|
4677
|
+
return <ApiCommand action={() => api.downloadModel(jobId)} />;
|
|
4678
|
+
}
|
|
4679
|
+
|
|
4680
|
+
if (artifactsAction === "delete") {
|
|
4681
|
+
if (!artifactArgs[0]) {
|
|
4682
|
+
return <ErrorMessage error="Model ID required: model artifacts delete <job-id>" />;
|
|
4683
|
+
}
|
|
4684
|
+
const jobId = artifactArgs[0];
|
|
4685
|
+
if (jobId.length !== 36) {
|
|
4686
|
+
return (
|
|
4687
|
+
<Box flexDirection="column">
|
|
4688
|
+
<ErrorMessage error="Invalid job ID: must be full UUID (36 characters)" />
|
|
4689
|
+
<Text dimColor> Provided: {jobId} ({jobId.length} characters)</Text>
|
|
4690
|
+
<Text dimColor> Tip: Use 'pioneer model artifacts list' to see full job IDs</Text>
|
|
4691
|
+
</Box>
|
|
4692
|
+
);
|
|
4693
|
+
}
|
|
4694
|
+
return (
|
|
4695
|
+
<ApiCommand
|
|
4696
|
+
action={() => api.deleteModel(jobId)}
|
|
4697
|
+
successMessage={`Model ${jobId} deleted`}
|
|
4698
|
+
/>
|
|
4699
|
+
);
|
|
4700
|
+
}
|
|
4701
|
+
|
|
4702
|
+
// Model upload command
|
|
4703
|
+
if (artifactsAction === "upload") {
|
|
4704
|
+
const destination = flags["to"];
|
|
4705
|
+
|
|
4706
|
+
if (!artifactArgs[0] && !destination) {
|
|
4707
|
+
return (
|
|
4708
|
+
<Box flexDirection="column">
|
|
4709
|
+
<Text bold>Model Upload:</Text>
|
|
4710
|
+
<Text> </Text>
|
|
4711
|
+
<Text> Upload to Hugging Face:</Text>
|
|
4712
|
+
<Text> model artifacts upload {"<job-id>"} --to hf --repo {"<repo>"} [--hf-token {"<token>"}] [--private]</Text>
|
|
4713
|
+
<Text> </Text>
|
|
4714
|
+
<Text dimColor> Supported destinations: hf (more coming soon)</Text>
|
|
4715
|
+
</Box>
|
|
4716
|
+
);
|
|
4717
|
+
}
|
|
4718
|
+
|
|
4719
|
+
if (destination === "hf") {
|
|
4720
|
+
if (!artifactArgs[0]) {
|
|
4721
|
+
return <ErrorMessage error="Job ID required: model artifacts upload <job-id> --to hf --repo <repo>" />;
|
|
4722
|
+
}
|
|
4723
|
+
const jobId = artifactArgs[0];
|
|
4724
|
+
const repo = flags["repo"];
|
|
4725
|
+
const hfTokenFlag = flags["hf-token"];
|
|
4726
|
+
const isPrivate = flags["private"]?.toLowerCase() === "true";
|
|
4727
|
+
|
|
4728
|
+
if (!repo) {
|
|
4729
|
+
return <ErrorMessage error="--repo is required (e.g., username/model-name)" />;
|
|
4730
|
+
}
|
|
4731
|
+
|
|
4732
|
+
const hfToken = getHfToken(hfTokenFlag);
|
|
4733
|
+
if (!hfToken) {
|
|
4734
|
+
return (
|
|
4735
|
+
<Box flexDirection="column">
|
|
4736
|
+
<ErrorMessage error="Hugging Face token required." />
|
|
4737
|
+
<Text> </Text>
|
|
4738
|
+
<Text>Set your token with:</Text>
|
|
4739
|
+
<Text color="cyan"> pioneer auth hf</Text>
|
|
4740
|
+
<Text> </Text>
|
|
4741
|
+
<Text dimColor>Get a token at: https://huggingface.co/settings/tokens</Text>
|
|
4742
|
+
</Box>
|
|
4743
|
+
);
|
|
4744
|
+
}
|
|
4745
|
+
|
|
4746
|
+
return (
|
|
4747
|
+
<ApiCommand
|
|
4748
|
+
action={() =>
|
|
4749
|
+
api.pushModelToHub(jobId, {
|
|
4750
|
+
hf_token: hfToken,
|
|
4751
|
+
repo_id: repo,
|
|
4752
|
+
private: isPrivate,
|
|
4753
|
+
})
|
|
4754
|
+
}
|
|
4755
|
+
successMessage={`Model uploaded to Hugging Face: ${repo}`}
|
|
4756
|
+
/>
|
|
4757
|
+
);
|
|
4758
|
+
}
|
|
4759
|
+
|
|
4760
|
+
return <ErrorMessage error="--to is required. Supported destinations: hf" />;
|
|
4761
|
+
}
|
|
4762
|
+
|
|
4763
|
+
return <Help context="model-artifacts" />;
|
|
2722
4764
|
}
|
|
2723
|
-
|
|
4765
|
+
|
|
4766
|
+
if (action === "predict" || action === "generate") {
|
|
4767
|
+
return (
|
|
4768
|
+
<ErrorMessage
|
|
4769
|
+
error={
|
|
4770
|
+
"model predict and model generate are no longer supported. Use model endpoints/... and model artifacts/... instead."
|
|
4771
|
+
}
|
|
4772
|
+
/>
|
|
4773
|
+
);
|
|
4774
|
+
}
|
|
4775
|
+
|
|
4776
|
+
return (
|
|
4777
|
+
<ErrorMessage
|
|
4778
|
+
error={`Unknown model command: model ${action}. Use 'pioneer model_endpoints ...', 'pioneer model endpoints ...', 'pioneer model_artifacts ...', or 'pioneer model artifacts ...'.`}
|
|
4779
|
+
/>
|
|
4780
|
+
);
|
|
2724
4781
|
}
|
|
2725
4782
|
|
|
2726
4783
|
// Eval commands
|
|
@@ -2738,9 +4795,60 @@ const App: React.FC<AppProps> = ({ command, flags }) => {
|
|
|
2738
4795
|
if (action === "list" && !rest[0]) {
|
|
2739
4796
|
return <ErrorMessage error="Dataset required: eval list <name[:version]>" />;
|
|
2740
4797
|
}
|
|
4798
|
+
if (action === "baseline-models") {
|
|
4799
|
+
return <ApiCommand action={api.listBaselineModels} />;
|
|
4800
|
+
}
|
|
2741
4801
|
if (action === "get" && rest[0]) {
|
|
2742
4802
|
return <ApiCommand action={() => api.getEvaluation(rest[0])} />;
|
|
2743
4803
|
}
|
|
4804
|
+
if (action === "delete" && rest[0]) {
|
|
4805
|
+
const evaluationId = rest[0];
|
|
4806
|
+
return (
|
|
4807
|
+
<ApiCommand
|
|
4808
|
+
action={async () => {
|
|
4809
|
+
const result = await api.deleteEvaluation(evaluationId);
|
|
4810
|
+
if (!result.ok && (result.status === 401 || result.status === 403) && result.error) {
|
|
4811
|
+
const lower = result.error.toLowerCase();
|
|
4812
|
+
const indicatesJwt = lower.includes("jwt") ||
|
|
4813
|
+
lower.includes("api key access") ||
|
|
4814
|
+
lower.includes("table") ||
|
|
4815
|
+
lower.includes("requires authentication");
|
|
4816
|
+
if (indicatesJwt) {
|
|
4817
|
+
return {
|
|
4818
|
+
ok: false,
|
|
4819
|
+
status: result.status,
|
|
4820
|
+
error:
|
|
4821
|
+
"Evaluation deletion requires a JWT-authenticated session. Run 'pioneer auth login' to sign in with your account credentials.",
|
|
4822
|
+
};
|
|
4823
|
+
}
|
|
4824
|
+
}
|
|
4825
|
+
return result;
|
|
4826
|
+
}}
|
|
4827
|
+
/>
|
|
4828
|
+
);
|
|
4829
|
+
}
|
|
4830
|
+
if (action === "update") {
|
|
4831
|
+
const mode = rest[0];
|
|
4832
|
+
const evaluationId = mode === "project" ? rest[1] : rest[0];
|
|
4833
|
+
if (!evaluationId) {
|
|
4834
|
+
return <Help context="eval" />;
|
|
4835
|
+
}
|
|
4836
|
+
const projectId = flags["project-id"];
|
|
4837
|
+
if (!projectId) {
|
|
4838
|
+
return <ErrorMessage error="--project-id is required" />;
|
|
4839
|
+
}
|
|
4840
|
+
return (
|
|
4841
|
+
<ApiCommand
|
|
4842
|
+
action={() =>
|
|
4843
|
+
api.updateEvaluationProject({
|
|
4844
|
+
evaluation_id: evaluationId,
|
|
4845
|
+
project_id: projectId,
|
|
4846
|
+
})
|
|
4847
|
+
}
|
|
4848
|
+
successMessage={`Evaluation ${evaluationId} reassigned`}
|
|
4849
|
+
/>
|
|
4850
|
+
);
|
|
4851
|
+
}
|
|
2744
4852
|
if (action === "create") {
|
|
2745
4853
|
const modelId = flags["model-id"];
|
|
2746
4854
|
const datasetStr = flags["dataset"];
|
|
@@ -2784,21 +4892,35 @@ const App: React.FC<AppProps> = ({ command, flags }) => {
|
|
|
2784
4892
|
return <ApiCommand action={api.listBenchmarks} />;
|
|
2785
4893
|
}
|
|
2786
4894
|
if (action === "run") {
|
|
2787
|
-
const
|
|
4895
|
+
const rawModelId = flags["model-id"];
|
|
2788
4896
|
const task = flags["task"] as "ner" | "text_classification";
|
|
2789
4897
|
const benchmark = flags["benchmark"];
|
|
2790
4898
|
const maxSamples = flags["max-samples"] ? parseInt(flags["max-samples"], 10) : undefined;
|
|
2791
4899
|
const split = flags["split"];
|
|
2792
4900
|
|
|
2793
|
-
if (!
|
|
4901
|
+
if (!rawModelId || !task || !benchmark) {
|
|
2794
4902
|
return <ErrorMessage error="--model-id, --task, and --benchmark are required" />;
|
|
2795
4903
|
}
|
|
4904
|
+
const normalizedModelId = normalizeModelId(rawModelId);
|
|
4905
|
+
if (!isUuid(normalizedModelId)) {
|
|
4906
|
+
return (
|
|
4907
|
+
<ErrorMessage
|
|
4908
|
+
error="Benchmark model-id must be a training job UUID (example: 72c1ac92-3a89-439d-afe3-687d8a935c06)."
|
|
4909
|
+
/>
|
|
4910
|
+
);
|
|
4911
|
+
}
|
|
4912
|
+
if (task !== "ner" && task !== "text_classification") {
|
|
4913
|
+
return <ErrorMessage error="--task must be either ner or text_classification" />;
|
|
4914
|
+
}
|
|
4915
|
+
if (maxSamples !== undefined && (Number.isNaN(maxSamples) || maxSamples < 1)) {
|
|
4916
|
+
return <ErrorMessage error="--max-samples must be a positive integer" />;
|
|
4917
|
+
}
|
|
2796
4918
|
|
|
2797
4919
|
return (
|
|
2798
4920
|
<ApiCommand
|
|
2799
4921
|
action={() =>
|
|
2800
4922
|
api.startBenchmarkEvaluation({
|
|
2801
|
-
model_id:
|
|
4923
|
+
model_id: normalizedModelId,
|
|
2802
4924
|
task,
|
|
2803
4925
|
benchmark,
|
|
2804
4926
|
max_samples: maxSamples,
|
|
@@ -2823,42 +4945,64 @@ const App: React.FC<AppProps> = ({ command, flags }) => {
|
|
|
2823
4945
|
return <Help context="benchmark" />;
|
|
2824
4946
|
}
|
|
2825
4947
|
|
|
2826
|
-
//
|
|
2827
|
-
if (group === "
|
|
2828
|
-
if (flags.help === "true" ||
|
|
2829
|
-
return <Help context="
|
|
2830
|
-
}
|
|
2831
|
-
if (action === "list") {
|
|
2832
|
-
return <CompetitionListCommand />;
|
|
2833
|
-
}
|
|
2834
|
-
if (action === "show" && rest[0]) {
|
|
2835
|
-
return <ApiCommand action={() => api.getCompetitionSamples(rest[0])} />;
|
|
2836
|
-
}
|
|
2837
|
-
if (action === "leaderboard" && rest[0]) {
|
|
2838
|
-
const limit = flags["limit"] ? parseInt(flags["limit"], 10) : undefined;
|
|
2839
|
-
return <LeaderboardCommand datasetId={rest[0]} limit={limit} />;
|
|
4948
|
+
// Adaptive agent commands (new short command)
|
|
4949
|
+
if (group === "agent") {
|
|
4950
|
+
if (flags.help === "true" || action === "help") {
|
|
4951
|
+
return <Help context="agent" />;
|
|
2840
4952
|
}
|
|
2841
|
-
if (action === "submit" && rest[0]) {
|
|
2842
|
-
const evalId = flags["eval-id"];
|
|
2843
|
-
const displayName = flags["name"];
|
|
2844
|
-
|
|
2845
|
-
if (!evalId || !displayName) {
|
|
2846
|
-
return <ErrorMessage error="--eval-id and --name are required" />;
|
|
2847
|
-
}
|
|
2848
4953
|
|
|
4954
|
+
if (action && !action.startsWith("-")) {
|
|
2849
4955
|
return (
|
|
2850
|
-
<
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
})
|
|
4956
|
+
<ErrorMessage
|
|
4957
|
+
error={
|
|
4958
|
+
'Invalid agent command syntax. Use one of:\n' +
|
|
4959
|
+
"pioneer agent\n" +
|
|
4960
|
+
"pioneer agent --mode research"
|
|
2856
4961
|
}
|
|
2857
|
-
successMessage="Submitted to leaderboard"
|
|
2858
4962
|
/>
|
|
2859
4963
|
);
|
|
2860
4964
|
}
|
|
2861
|
-
|
|
4965
|
+
|
|
4966
|
+
if (flags.message) {
|
|
4967
|
+
return <ErrorMessage error="The --message flag has been removed for agent. Run `pioneer agent` or `pioneer agent --mode research` and provide input interactively." />;
|
|
4968
|
+
}
|
|
4969
|
+
|
|
4970
|
+
const rawMode = flags.mode;
|
|
4971
|
+
const validModes = ["research"];
|
|
4972
|
+
const normalizedMode = rawMode ? rawMode.toLowerCase() : undefined;
|
|
4973
|
+
if (normalizedMode && !validModes.includes(normalizedMode)) {
|
|
4974
|
+
return <ErrorMessage error="--mode must be one of: research" />;
|
|
4975
|
+
}
|
|
4976
|
+
const mode = (normalizedMode === "research" ? "research" : "standard") as "standard" | "research";
|
|
4977
|
+
|
|
4978
|
+
let history: api.AgentChatHistoryItem[] | undefined;
|
|
4979
|
+
if (flags.history) {
|
|
4980
|
+
try {
|
|
4981
|
+
const parsed = JSON.parse(flags.history) as unknown;
|
|
4982
|
+
if (!Array.isArray(parsed)) {
|
|
4983
|
+
return <ErrorMessage error="--history must be a JSON array" />;
|
|
4984
|
+
}
|
|
4985
|
+
history = parsed as api.AgentChatHistoryItem[];
|
|
4986
|
+
} catch {
|
|
4987
|
+
return <ErrorMessage error="--history must be valid JSON" />;
|
|
4988
|
+
}
|
|
4989
|
+
}
|
|
4990
|
+
|
|
4991
|
+
if (flags.filters) {
|
|
4992
|
+
return <ErrorMessage error='--filters is not supported for /auto-agent/clarify. Omit this flag for now.' />;
|
|
4993
|
+
}
|
|
4994
|
+
|
|
4995
|
+
return (
|
|
4996
|
+
<AgentInteractivePrompt
|
|
4997
|
+
conversationId={flags["conversation-id"]}
|
|
4998
|
+
history={history}
|
|
4999
|
+
mode={mode}
|
|
5000
|
+
/>
|
|
5001
|
+
);
|
|
5002
|
+
}
|
|
5003
|
+
|
|
5004
|
+
if (group === "notebook") {
|
|
5005
|
+
return <ErrorMessage error="The notebook command is deprecated and has been removed from this CLI." />;
|
|
2862
5006
|
}
|
|
2863
5007
|
|
|
2864
5008
|
return <Help />;
|
|
@@ -2872,7 +5016,7 @@ import packageJson from "../package.json";
|
|
|
2872
5016
|
|
|
2873
5017
|
async function main() {
|
|
2874
5018
|
const argv = process.argv.slice(2);
|
|
2875
|
-
const { command, flags } = parseArgs(argv);
|
|
5019
|
+
const { command, flags, parseErrors } = parseArgs(argv);
|
|
2876
5020
|
|
|
2877
5021
|
// Handle version flag early (before React render)
|
|
2878
5022
|
if (flags.version === "true" || flags.v === "true") {
|
|
@@ -2880,7 +5024,7 @@ async function main() {
|
|
|
2880
5024
|
process.exit(0);
|
|
2881
5025
|
}
|
|
2882
5026
|
|
|
2883
|
-
await render(<App command={command} flags={flags} />).waitUntilExit();
|
|
5027
|
+
await render(<App command={command} flags={flags} parseErrors={parseErrors} />).waitUntilExit();
|
|
2884
5028
|
}
|
|
2885
5029
|
|
|
2886
5030
|
main();
|